[development] Migrated Atom CPU profiler to utilize new AzCore Profiler interface and related macros (#4160)

- Added new interface type AZ::Debug::Profiler to externally register profiler systems
 - Modified the Atom CPU profiler to register as an AzCore profiler
 -- This allows full engine markers to be visualized in the associated ImGui tool
 - Converted all AZ_ATOM_PROFILE_* macros to use AZ_PROFILE_* macros instead

Signed-off-by: AMZN-ScottR 24445312+AMZN-ScottR@users.noreply.github.com
This commit is contained in:
Scott Romero
2021-09-20 11:40:57 -07:00
committed by GitHub
parent 6565b91854
commit 36bcf5849a
72 changed files with 239 additions and 336 deletions
@@ -59,6 +59,20 @@ namespace AZStd
namespace AZ::Debug
{
// interface for externally defined profiler systems
class Profiler
{
public:
AZ_RTTI(Profiler, "{3E5D6329-72D1-41BA-9158-68A349D1A4D5}");
Profiler() = default;
virtual ~Profiler() = default;
// support for the extra macro args (e.g. format strings) will come in a later PR
virtual void BeginRegion(const Budget* budget, const char* eventName) = 0;
virtual void EndRegion(const Budget* budget) = 0;
};
class ProfileScope
{
public:
@@ -6,6 +6,8 @@
*
*/
#include <AzCore/Interface/Interface.h>
namespace AZ::Debug
{
template<typename... T>
@@ -22,9 +24,11 @@ namespace AZ::Debug
PIXBeginEvent(PIX_COLOR_INDEX(budget->Crc() & 0xff), eventName, args...);
#endif
budget->BeginProfileRegion();
// TODO: injecting instrumentation for other profilers
// NOTE: external profiler registration won't occur inline in a header necessarily in this manner, but the exact mechanism
// will be introduced in a future PR
if (auto profiler = AZ::Interface<Profiler>::Get(); profiler)
{
profiler->BeginRegion(budget, eventName);
}
#endif
}
@@ -39,6 +43,10 @@ namespace AZ::Debug
#if defined(USE_PIX)
PIXEndEvent();
#endif
if (auto profiler = AZ::Interface<Profiler>::Get(); profiler)
{
profiler->EndRegion(budget);
}
#endif
}
@@ -565,7 +565,7 @@ namespace AZ
AuxGeomBufferData* AuxGeomDrawQueue::Commit()
{
AZ_ATOM_PROFILE_FUNCTION("AuxGeom", "AuxGeomDrawQueue: Commit");
AZ_PROFILE_SCOPE(AzRender, "AuxGeomDrawQueue: Commit");
// get a mutually exclusive lock and then switch to the next buffer, returning a pointer to the current buffer (before the switch)
// grab the lock
@@ -585,7 +585,7 @@ namespace AZ
void AuxGeomDrawQueue::ClearCurrentBufferData()
{
AZ_ATOM_PROFILE_FUNCTION("AuxGeom", "AuxGeomDrawQueue: ClearCurrentBufferData");
AZ_PROFILE_SCOPE(AzRender, "AuxGeomDrawQueue: ClearCurrentBufferData");
// no need for mutex here, this function is only called from a function holding a lock
AuxGeomBufferData& data = m_buffers[m_currentBufferIndex];
@@ -649,7 +649,7 @@ namespace AZ
AZ::u8 width,
int32_t viewProjOverrideIndex)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "AuxGeomDrawQueue: DrawPrimitiveWithSharedVerticesCommon");
// grab a mutex lock for the rest of this function so that a commit cannot happen during it and
// other threads can't add geometry during it
@@ -720,8 +720,7 @@ namespace AZ
AZ::u8 width,
int32_t viewProjOverrideIndex)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("AuxGeom", "AuxGeomDrawQueue: DrawPrimitiveWithSharedVerticesCommon");
AZ_PROFILE_SCOPE(AzRender, "AuxGeomDrawQueue: DrawPrimitiveWithSharedVerticesCommon");
AZ_Assert(indexCount >= verticesPerPrimitiveType && (indexCount % verticesPerPrimitiveType == 0),
"Index count must be at least %d and must be a multiple of %d",
@@ -80,7 +80,7 @@ namespace AZ
void AuxGeomFeatureProcessor::Render(const FeatureProcessor::RenderPacket& fpPacket)
{
AZ_ATOM_PROFILE_FUNCTION("AuxGeom", "AuxGeomFeatureProcessor: Render");
AZ_PROFILE_SCOPE(AzRender, "AuxGeomFeatureProcessor: Render");
// Get the scene data and switch buffers so that other threads can continue to queue requests
AuxGeomBufferData* bufferData = static_cast<AuxGeomDrawQueue*>(m_sceneDrawQueue.get())->Commit();
@@ -70,7 +70,7 @@ namespace AZ
void DynamicPrimitiveProcessor::PrepareFrame()
{
AZ_ATOM_PROFILE_FUNCTION("AuxGeom", "DynamicPrimitiveProcessor: PrepareFrame");
AZ_PROFILE_SCOPE(AzRender, "DynamicPrimitiveProcessor: PrepareFrame");
m_drawPackets.clear();
m_processSrgs.clear();
@@ -88,7 +88,7 @@ namespace AZ
void DynamicPrimitiveProcessor::ProcessDynamicPrimitives(const AuxGeomBufferData* bufferData, const RPI::FeatureProcessor::RenderPacket& fpPacket)
{
AZ_ATOM_PROFILE_FUNCTION("AuxGeom", "DynamicPrimitiveProcessor: ProcessDynamicPrimitives");
AZ_PROFILE_SCOPE(AzRender, "DynamicPrimitiveProcessor: ProcessDynamicPrimitives");
RHI::DrawPacketBuilder drawPacketBuilder;
const DynamicPrimitiveData& srcPrimitives = bufferData->m_primitiveData;
@@ -108,8 +108,8 @@ namespace AZ
}
void FixedShapeProcessor::PrepareFrame()
{
AZ_ATOM_PROFILE_FUNCTION("AuxGeom", "FixedShapeProcessor: PrepareFrame");
{
AZ_PROFILE_SCOPE(AzRender, "FixedShapeProcessor: PrepareFrame");
m_processSrgs.clear();
m_drawPackets.clear();
@@ -127,8 +127,7 @@ namespace AZ
void FixedShapeProcessor::ProcessObjects(const AuxGeomBufferData* bufferData, const RPI::FeatureProcessor::RenderPacket& fpPacket)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("AuxGeom", "FixedShapeProcessor: ProcessObjects");
AZ_PROFILE_SCOPE(AzRender, "FixedShapeProcessor: ProcessObjects");
RHI::DrawPacketBuilder drawPacketBuilder;
@@ -102,7 +102,7 @@ namespace AZ
void CapsuleLightFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "CapsuleLightFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "CapsuleLightFeatureProcessor: Simulate");
AZ_UNUSED(packet);
if (m_deviceBufferNeedsUpdate)
@@ -114,7 +114,7 @@ namespace AZ
void CapsuleLightFeatureProcessor::Render(const CapsuleLightFeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "CapsuleLightFeatureProcessor: Render");
AZ_PROFILE_SCOPE(RPI, "CapsuleLightFeatureProcessor: Render");
for (const RPI::ViewPtr& view : packet.m_views)
{
@@ -196,7 +196,7 @@ namespace AZ
void DirectionalLightFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket&)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "DirectionalLightFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "DirectionalLightFeatureProcessor: Simulate");
if (m_shadowingLightHandle.IsValid())
{
@@ -293,7 +293,7 @@ namespace AZ
void DirectionalLightFeatureProcessor::Render(const FeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "DirectionalLightFeatureProcessor: Render");
AZ_PROFILE_SCOPE(RPI, "DirectionalLightFeatureProcessor: Render");
if (m_shadowingLightHandle.IsValid())
{
@@ -1232,7 +1232,7 @@ namespace AZ
void DirectionalLightFeatureProcessor::SetFilterParameterToPass(LightHandle handle, const RPI::View* cameraView)
{
AZ_ATOM_PROFILE_FUNCTION("DirectionalLightFeatureProcessor", "DirectionalLightFeatureProcessor::SetFilterParameterToPass");
AZ_PROFILE_SCOPE(RPI, "DirectionalLightFeatureProcessor::SetFilterParameterToPass");
if (handle != m_shadowingLightHandle)
{
@@ -123,7 +123,7 @@ namespace AZ
void DiskLightFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "DiskLightFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "DiskLightFeatureProcessor: Simulate");
AZ_UNUSED(packet);
if (m_deviceBufferNeedsUpdate)
@@ -135,7 +135,7 @@ namespace AZ
void DiskLightFeatureProcessor::Render(const DiskLightFeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "DiskLightFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "DiskLightFeatureProcessor: Simulate");
for (const RPI::ViewPtr& view : packet.m_views)
{
@@ -119,7 +119,7 @@ namespace AZ
void PointLightFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "PointLightFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "PointLightFeatureProcessor: Simulate");
AZ_UNUSED(packet);
if (m_deviceBufferNeedsUpdate)
@@ -131,7 +131,7 @@ namespace AZ
void PointLightFeatureProcessor::Render(const PointLightFeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "PointLightFeatureProcessor: Render");
AZ_PROFILE_SCOPE(RPI, "PointLightFeatureProcessor: Render");
for (const RPI::ViewPtr& view : packet.m_views)
{
@@ -132,7 +132,7 @@ namespace AZ::Render
void PolygonLightFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "PolygonLightFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "PolygonLightFeatureProcessor: Simulate");
AZ_UNUSED(packet);
if (m_deviceBufferNeedsUpdate)
@@ -153,7 +153,7 @@ namespace AZ::Render
void PolygonLightFeatureProcessor::Render(const PolygonLightFeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "PolygonLightFeatureProcessor: Render");
AZ_PROFILE_SCOPE(RPI, "PolygonLightFeatureProcessor: Render");
for (const RPI::ViewPtr& view : packet.m_views)
{
@@ -107,7 +107,7 @@ namespace AZ
void QuadLightFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "QuadLightFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "QuadLightFeatureProcessor: Simulate");
AZ_UNUSED(packet);
if (m_deviceBufferNeedsUpdate)
@@ -119,7 +119,7 @@ namespace AZ
void QuadLightFeatureProcessor::Render(const QuadLightFeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "QuadLightFeatureProcessor: Render");
AZ_PROFILE_SCOPE(RPI, "QuadLightFeatureProcessor: Render");
for (const RPI::ViewPtr& view : packet.m_views)
{
@@ -102,7 +102,7 @@ namespace AZ
void SimplePointLightFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "SimplePointLightFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "SimplePointLightFeatureProcessor: Simulate");
AZ_UNUSED(packet);
if (m_deviceBufferNeedsUpdate)
@@ -114,7 +114,7 @@ namespace AZ
void SimplePointLightFeatureProcessor::Render(const SimplePointLightFeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "SimplePointLightFeatureProcessor: Render");
AZ_PROFILE_SCOPE(RPI, "SimplePointLightFeatureProcessor: Render");
for (const RPI::ViewPtr& view : packet.m_views)
{
@@ -102,7 +102,7 @@ namespace AZ
void SimpleSpotLightFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "SimpleSpotLightFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "SimpleSpotLightFeatureProcessor: Simulate");
AZ_UNUSED(packet);
if (m_deviceBufferNeedsUpdate)
@@ -114,7 +114,7 @@ namespace AZ
void SimpleSpotLightFeatureProcessor::Render(const SimpleSpotLightFeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "SimpleSpotLightFeatureProcessor: Render");
AZ_PROFILE_SCOPE(RPI, "SimpleSpotLightFeatureProcessor: Render");
for (const RPI::ViewPtr& view : packet.m_views)
{
@@ -107,7 +107,7 @@ namespace AZ
void DecalFeatureProcessor::Simulate(const RPI::FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "DecalFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "DecalFeatureProcessor: Simulate");
AZ_UNUSED(packet);
if (m_deviceBufferNeedsUpdate)
@@ -131,7 +131,7 @@ namespace AZ
void DecalFeatureProcessor::Render(const RPI::FeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "DecalFeatureProcessor: Render");
AZ_PROFILE_SCOPE(RPI, "DecalFeatureProcessor: Render");
AZStd::array_view<Data::Instance<RPI::Image>> baseMaps = GetImagesFromDecalData<1>();
AZStd::array_view<Data::Instance<RPI::Image>> opacityMaps = GetImagesFromDecalData<2>();
@@ -145,7 +145,7 @@ namespace AZ
void DecalTextureArrayFeatureProcessor::Simulate(const RPI::FeatureProcessor::SimulatePacket& packet)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "DecalTextureArrayFeatureProcessor: Simulate");
AZ_UNUSED(packet);
if (m_deviceBufferNeedsUpdate)
@@ -158,7 +158,7 @@ namespace AZ
void DecalTextureArrayFeatureProcessor::Render(const RPI::FeatureProcessor::RenderPacket& packet)
{
// Note that decals are rendered as part of the forward shading pipeline. We only need to bind the decal buffers/textures in here.
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "DecalTextureArrayFeatureProcessor: Render");
for (const RPI::ViewPtr& view : packet.m_views)
{
@@ -294,7 +294,7 @@ namespace AZ
void DecalTextureArrayFeatureProcessor::SetDecalMaterial(const DecalHandle handle, const AZ::Data::AssetId material)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "DecalTextureArrayFeatureProcessor: SetDecalMaterial");
if (handle.IsNull())
{
AZ_Warning("DecalTextureArrayFeatureProcessor", false, "Invalid handle passed to DecalTextureArrayFeatureProcessor::SetDecalMaterial().");
@@ -364,7 +364,7 @@ namespace AZ
void DecalTextureArrayFeatureProcessor::OnAssetReady(const Data::Asset<Data::AssetData> asset)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "DecalTextureArrayFeatureProcessor: OnAssetReady");
const Data::AssetId& assetId = asset->GetId();
const RPI::MaterialAsset* materialAsset = asset.GetAs<AZ::RPI::MaterialAsset>();
@@ -111,7 +111,7 @@ namespace AZ
void DiffuseProbeGridFeatureProcessor::Simulate([[maybe_unused]] const FeatureProcessor::SimulatePacket& packet)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "DiffuseProbeGridFeatureProcessor: Simulate");
// update pipeline states
if (m_needUpdatePipelineStates)
@@ -577,8 +577,7 @@ namespace AZ
void ImGuiPass::BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("Pass", "ImGuiPass: Execute");
AZ_PROFILE_SCOPE(AzRender, "ImGuiPass: BuildCommandListInternal");
context.GetCommandList()->SetViewport(m_viewportState);
@@ -607,8 +606,7 @@ namespace AZ
uint32_t ImGuiPass::UpdateImGuiResources()
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("Pass", "ImGuiPass: UpdateImGuiResources");
AZ_PROFILE_SCOPE(AzRender, "ImGuiPass: UpdateImGuiResources");
auto imguiContextScope = ImguiContextScope(m_imguiContext);
@@ -50,7 +50,7 @@ namespace AZ
void ImageBasedLightFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "ImageBasedLightFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "ImageBasedLightFeatureProcessor: Simulate");
AZ_UNUSED(packet);
m_sceneSrg->SetImage(m_specularEnvMapIndex, m_specular);
@@ -75,8 +75,7 @@ namespace AZ
void MeshFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("RPI", "MeshFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "MeshFeatureProcessor: Simulate");
AZ_UNUSED(packet);
AZStd::concurrency_check_scope scopeCheck(m_meshDataChecker);
@@ -149,7 +148,7 @@ namespace AZ
const MeshHandleDescriptor& descriptor,
const MaterialAssignmentMap& materials)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "MeshFeatureProcessor: AcquireMesh");
// don't need to check the concurrency during emplace() because the StableDynamicArray won't move the other elements during insertion
MeshHandle meshDataHandle = m_meshData.emplace();
@@ -984,7 +983,7 @@ namespace AZ
void MeshDataInstance::UpdateDrawPackets(bool forceUpdate /*= false*/)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "MeshDataInstance:: UpdateDrawPackets");
for (auto& drawPacketList : m_drawPacketListsByLod)
{
for (auto& drawPacket : drawPacketList)
@@ -999,7 +998,7 @@ namespace AZ
void MeshDataInstance::BuildCullable()
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "MeshDataInstance: BuildCullable");
AZ_Assert(m_cullableNeedsRebuild, "This function only needs to be called if the cullable to be rebuilt");
AZ_Assert(m_model, "The model has not finished loading yet");
@@ -1076,7 +1075,7 @@ namespace AZ
void MeshDataInstance::UpdateCullBounds(const TransformServiceFeatureProcessor* transformService)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "MeshDataInstance: UpdateCullBounds");
AZ_Assert(m_cullBoundsNeedsUpdate, "This function only needs to be called if the culling bounds need to be rebuilt");
AZ_Assert(m_model, "The model has not finished loading yet");
@@ -49,7 +49,7 @@ namespace AZ
void PostProcessFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "PostProcessFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "PostProcessFeatureProcessor: Simulate");
AZ_UNUSED(packet);
UpdateTime();
@@ -161,7 +161,7 @@ namespace AZ
void SMAAFeatureProcessor::Render([[maybe_unused]] const SMAAFeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "SMAAFeatureProcessor: Render");
AZ_PROFILE_SCOPE(RPI, "SMAAFeatureProcessor: Render");
UpdateConvertToPerceptualPass();
UpdateEdgeDetectionPass();
@@ -154,8 +154,7 @@ namespace AZ
void ReflectionProbeFeatureProcessor::Simulate([[maybe_unused]] const FeatureProcessor::SimulatePacket& packet)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("ReflectionProbe", "ReflectionProbeFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(AzRender, "ReflectionProbeFeatureProcessor: Simulate");
// update pipeline states
if (m_needUpdatePipelineStates)
@@ -194,7 +193,6 @@ namespace AZ
if (m_probeSortRequired)
{
AZ_PROFILE_SCOPE(AzRender, "Sort reflection probes");
AZ_ATOM_PROFILE_FUNCTION("ReflectionProbe", "ReflectionProbeFeatureProcessor: Sort reflection probes");
// sort the probes by descending inner volume size, so the smallest volumes are rendered last
auto sortFn = [](AZStd::shared_ptr<ReflectionProbe> const& probe1, AZStd::shared_ptr<ReflectionProbe> const& probe2) -> bool
@@ -486,7 +486,7 @@ namespace AZ::Render
void ProjectedShadowFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& /*packet*/)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "ProjectedShadowFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "ProjectedShadowFeatureProcessor: Simulate");
if (m_shadowmapPassNeedsUpdate)
{
@@ -581,7 +581,7 @@ namespace AZ::Render
void ProjectedShadowFeatureProcessor::Render(const ProjectedShadowFeatureProcessor::RenderPacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "ProjectedShadowFeatureProcessor: Render");
AZ_PROFILE_SCOPE(RPI, "ProjectedShadowFeatureProcessor: Render");
if (!m_projectedShadowmapsPasses.empty())
{
@@ -69,8 +69,7 @@ namespace AZ
void SkinnedMeshFeatureProcessor::Render(const FeatureProcessor::RenderPacket& packet)
{
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("SkinnedMesh", "SkinnedMeshFeatureProcessor: Render");
AZ_PROFILE_SCOPE(AzRender, "SkinnedMeshFeatureProcessor: Render");
#if 0 //[GFX_TODO][ATOM-13564] Temporarily disable skinning culling until we figure out how to hook up visibility & lod selection with skinning:
//Setup the culling workgroup (it will be re-used for each view)
@@ -534,7 +534,7 @@ namespace AZ
// lod0 Positions[^ ^] lod0Normals[^ ^] lod1Positions[^ ^] lod1Normals[^ ^]
// lod0 subMesh0+1 Positions[^ ^^ ^] lod0 subMesh0+1 Normals[^ ^^ ^] lod1 sm0+1 pos[^ ^^ ^] lod1 sm0+1 norm[^ ^^ ^]
AZ_PROFILE_FUNCTION(AzRender);
AZ_PROFILE_SCOPE(AzRender, "SkinnedMeshInputBuffers: CreateSkinnedMeshInstance");
AZStd::intrusive_ptr<SkinnedMeshInstance> instance = aznew SkinnedMeshInstance;
// Each model gets a unique, random ID, so if the same source model is used for multiple instances, multiple target models will be created.
@@ -105,7 +105,7 @@ namespace AZ
void SkyBoxFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "SkyBoxFeatureProcessor: Simulate");
AZ_PROFILE_SCOPE(RPI, "SkyBoxFeatureProcessor: Simulate");
AZ_UNUSED(packet);
m_sceneSrg->SetConstant(m_skyboxEnableIndex, m_enable);
@@ -9,6 +9,7 @@
#pragma once
#include <AzCore/Debug/EventTrace.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/containers/ring_buffer.h>
#include <AzCore/std/containers/unordered_map.h>
@@ -21,15 +22,15 @@ namespace AZ
//! Structure that is used to cache a timed region into the thread's local storage.
struct CachedTimeRegion
{
//! Structure that the profiling macro utilizes to create statically initialized instance to create string
//! literals in static memory
//! Structure used internally for caching assumed global string pointers (ideally literals) to the marker group/region
//! NOTE: When used in a separate shared library, the library mustn't be unloaded before the CpuProfiler is shutdown.
struct GroupRegionName
{
GroupRegionName() = delete;
GroupRegionName(const char* const group, const char* const region);
const char* const m_groupName = nullptr;
const char* const m_regionName = nullptr;
const char* m_groupName = nullptr;
const char* m_regionName = nullptr;
struct Hash
{
@@ -39,31 +40,16 @@ namespace AZ
};
CachedTimeRegion() = default;
CachedTimeRegion(const GroupRegionName* groupRegionName);
CachedTimeRegion(const GroupRegionName* groupRegionName, uint16_t stackDepth, uint64_t startTick, uint64_t endTick);
CachedTimeRegion(const GroupRegionName& groupRegionName);
CachedTimeRegion(const GroupRegionName& groupRegionName, uint16_t stackDepth, uint64_t startTick, uint64_t endTick);
//! Pointer to the GroupRegionName static instance.
//! NOTE: When used in a separate shared library, the library mustn't be unloaded before
//! the CpuProfiler is shutdown.
const GroupRegionName* m_groupRegionName = nullptr;
GroupRegionName m_groupRegionName{nullptr, nullptr};
uint16_t m_stackDepth = 0u;
AZStd::sys_time_t m_startTick = 0;
AZStd::sys_time_t m_endTick = 0;
};
//! Helper class used as a RAII-style mechanism for the macros to begin and end a region.
class TimeRegion : public CachedTimeRegion
{
public:
TimeRegion() = delete;
TimeRegion(const GroupRegionName* groupRegionName);
~TimeRegion();
//! End region
void EndRegion();
};
//! Interface class of the CpuProfiler
class CpuProfiler
{
@@ -80,12 +66,6 @@ namespace AZ
static CpuProfiler* Get();
//! Add a new time region
virtual void BeginTimeRegion(TimeRegion& timeRegion) = 0;
//! Ends a time region
virtual void EndTimeRegion() = 0;
//! Get the last frame's TimeRegionMap
virtual const TimeRegionMap& GetTimeRegionMap() const = 0;
@@ -101,38 +81,7 @@ namespace AZ
virtual void SetProfilerEnabled(bool enabled) = 0;
virtual bool IsProfilerEnabled() const = 0 ;
//! Used by AZ_ATOM_PROFILE_DYNAMIC to create GroupRegionNames with known lifetimes.
virtual const CachedTimeRegion::GroupRegionName& InsertDynamicName(const char* groupName, const AZStd::string& regionName) = 0;
};
} // namespace RPI
} // namespace AZ
//! Utility functions for timing a section of code and writing the timing (in cycles) to a new, named time region inside the
//! provided statistics data.
//! Supply a group and region to the time region
#define AZ_ATOM_PROFILE_TIME_GROUP_REGION(groupName, regionName) \
static const AZ::RHI::CachedTimeRegion::GroupRegionName AZ_JOIN(groupRegionName, __LINE__)(groupName, regionName); \
AZ::RHI::TimeRegion AZ_JOIN(timeRegion, __LINE__)(&AZ_JOIN(groupRegionName, __LINE__));
//! Supply a region to the time region; "Default" will be used for the group
#define AZ_ATOM_PROFILE_TIME_REGION(regionName) \
AZ_ATOM_PROFILE_TIME_GROUP_REGION("Default", regionName)
//! Used to create a time region; "Default" will be used for the group, and __FUNCTION__ macro for the region
#define AZ_ATOM_PROFILE_TIME_FUNCTION() \
AZ_ATOM_PROFILE_TIME_GROUP_REGION("Default", AZ_FUNCTION_SIGNATURE)
//! Macro that combines the AZ_TRACE_METHOD with time profiling macro
#define AZ_ATOM_PROFILE_FUNCTION(groupName, regionName) \
AZ_TRACE_METHOD(); \
AZ_ATOM_PROFILE_TIME_GROUP_REGION(groupName, regionName) \
//! Macro that allows for region names to be submitted at runtime. Use sparingly - this acquires a lock and allocates new objects within a map.
#define AZ_ATOM_PROFILE_DYNAMIC(groupName, regionName) \
static_assert(AZStd::is_convertible_v<decltype(groupName), const char*>, "Runtime group names are not allowed, use a static string literal instead."); \
const AZ::RHI::CachedTimeRegion::GroupRegionName& AZ_JOIN(groupRegionName, __LINE__) = \
AZ::RHI::CpuProfiler::Get()->InsertDynamicName(groupName, regionName); \
AZ::RHI::TimeRegion AZ_JOIN(timeRegion, __LINE__)(&AZ_JOIN(groupRegionName, __LINE__));
@@ -43,13 +43,13 @@ namespace AZ
static constexpr uint32_t TimeRegionStackSize = 2048u;
// Adds a region to the stack, gets called each time a region begins
void RegionStackPushBack(TimeRegion& timeRegion);
void RegionStackPushBack(CachedTimeRegion& timeRegion);
// Pops a region from the stack, gets called each time a region ends
void RegionStackPopBack();
// Add a new cached time region. If the stack is empty, flush all entries to the cached map
void AddCachedRegion(CachedTimeRegion&& timeRegionCached);
void AddCachedRegion(const CachedTimeRegion& timeRegionCached);
// Tries to flush the map to the passed parameter, only if the thread's mutex is unlocked
void TryFlushCachedMap(CpuProfiler::ThreadTimeRegionMap& cachedRegionMap);
@@ -63,7 +63,7 @@ namespace AZ
// Use fixed vectors to avoid re-allocating new elements
// Keeps track of the regions that added and removed using the macro
AZStd::fixed_vector<TimeRegion*, TimeRegionStackSize> m_timeRegionStack;
AZStd::fixed_vector<CachedTimeRegion, TimeRegionStackSize> m_timeRegionStack;
// Keeps track of regions that completed (i.e regions that was pushed and popped from the stack)
// Intermediate storage point for the CachedTimeRegions, when the stack is empty, all entries will be
@@ -85,7 +85,8 @@ namespace AZ
//! forwards the request to profile a region to the appropriate thread. The user is able to request all
//! cached regions, which are stored on a per thread frequency.
class CpuProfilerImpl final
: public CpuProfiler
: public AZ::Debug::Profiler
, public CpuProfiler
, public SystemTickBus::Handler
{
friend class CpuTimingLocalStorage;
@@ -107,16 +108,17 @@ namespace AZ
// m_timeRegionMap so that the next frame has up-to-date profiling data.
void OnSystemTick() final override;
//! AZ::Debug::Profiler overrides...
void BeginRegion(const AZ::Debug::Budget* budget, const char* eventName) final override;
void EndRegion(const AZ::Debug::Budget* budget) final override;
//! CpuProfiler overrides...
void BeginTimeRegion(TimeRegion& timeRegion) final override;
void EndTimeRegion() final override;
const TimeRegionMap& GetTimeRegionMap() const final override;
bool BeginContinuousCapture() final override;
bool EndContinuousCapture(AZStd::ring_buffer<TimeRegionMap>& flushTarget) final override;
bool IsContinuousCaptureInProgress() const final override;
void SetProfilerEnabled(bool enabled) final override;
bool IsProfilerEnabled() const final override;
const CachedTimeRegion::GroupRegionName& InsertDynamicName(const char* groupName, const AZStd::string& regionName) final override;
private:
static constexpr AZStd::size_t MaxFramesToSave = 2 * 60 * 120; // 2 minutes of 120fps
@@ -133,15 +135,6 @@ namespace AZ
AZStd::vector<RHI::Ptr<CpuTimingLocalStorage>, AZ::OSStdAllocator> m_registeredThreads;
AZStd::mutex m_threadRegisterMutex;
// Pool for GroupRegionNames that are generated at runtime through AZ_ATOM_PROFILE_DYNAMIC. Each unique
// combination of group name and region name submitted will be stored in this pool to emulate static lifetime.
AZStd::unordered_set<CachedTimeRegion::GroupRegionName, CachedTimeRegion::GroupRegionName::Hash> m_dynamicGroupRegionNamePool;
// String pool for storing region names submitted at runtime. Each call to AZ_ATOM_PROFILE_DYNAMIC will either construct
// a string in this pool or use an already-existing entry.
AZStd::unordered_set<AZStd::string> m_regionNameStringPool;
AZStd::mutex m_dynamicNameMutex;
// Thread local storage, gets lazily allocated when a thread is created
static thread_local CpuTimingLocalStorage* ms_threadLocalStorage;
@@ -157,7 +157,7 @@ namespace AZ
template <class Traits>
void MemorySubAllocator<Traits>::GarbageCollect()
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "MemorySubAllocator: GarbageCollect");
AZ_PROFILE_SCOPE(RHI, "MemorySubAllocator: GarbageCollect");
for (PageContext& pageContext : m_pageContexts)
{
pageContext.m_allocator.GarbageCollect();
@@ -173,7 +173,7 @@ namespace AZ
template <typename Traits>
void ObjectCollector<Traits>::Collect(bool forceFlush)
{
AZ_ATOM_PROFILE_FUNCTION("DX12", "ObjectCollector: Collect");
AZ_PROFILE_SCOPE(RHI, "ObjectCollector: Collect");
m_mutex.lock();
if (m_pendingObjects.size())
{
@@ -128,7 +128,7 @@ namespace AZ
return;
}
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "AsyncWorkQueue: WaitToFinish");
AZStd::unique_lock<AZStd::mutex> lock(m_waitWorkItemMutex);
m_waitWorkItemCondition.wait(lock, [&]() {return HasFinishedWork(workHandle); });
+1 -1
View File
@@ -163,7 +163,7 @@ namespace AZ
return ResultCode::InvalidArgument;
}
AZ_ATOM_PROFILE_FUNCTION("RHI", "BufferPool::OrphanBuffer");
AZ_PROFILE_SCOPE(RHI, "BufferPool::OrphanBuffer");
return OrphanBufferInternal(buffer);
}
@@ -22,7 +22,7 @@ namespace AZ
ResultCode CommandQueue::Init(Device& device, const CommandQueueDescriptor& descriptor)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "CommandQueue: Init");
#if defined (AZ_RHI_ENABLE_VALIDATION)
if (IsInitialized())
@@ -83,7 +83,7 @@ namespace AZ
void CommandQueue::FlushCommands()
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "CommandQueue: FlushCommands");
AZ_PROFILE_SCOPE(RHI, "CommandQueue: FlushCommands");
while (!m_isWorkQueueEmpty && !m_isQuitting)
{
AZStd::this_thread::yield();
@@ -27,38 +27,14 @@ namespace AZ
return Interface<CpuProfiler>::Get();
}
// --- TimeRegion ---
TimeRegion::TimeRegion(const GroupRegionName* groupRegionName) :
CachedTimeRegion(groupRegionName)
{
if (CpuProfiler::Get())
{
CpuProfiler::Get()->BeginTimeRegion(*this);
}
}
TimeRegion::~TimeRegion()
{
EndRegion();
}
void TimeRegion::EndRegion()
{
if (CpuProfiler::Get())
{
CpuProfiler::Get()->EndTimeRegion();
}
}
// --- CachedTimeRegion ---
CachedTimeRegion::CachedTimeRegion(const GroupRegionName* groupRegionName)
CachedTimeRegion::CachedTimeRegion(const GroupRegionName& groupRegionName)
{
m_groupRegionName = groupRegionName;
}
CachedTimeRegion::CachedTimeRegion(const GroupRegionName* groupRegionName, uint16_t stackDepth, uint64_t startTick, uint64_t endTick)
CachedTimeRegion::CachedTimeRegion(const GroupRegionName& groupRegionName, uint16_t stackDepth, uint64_t startTick, uint64_t endTick)
{
m_groupRegionName = groupRegionName;
m_stackDepth = stackDepth;
@@ -92,6 +68,7 @@ namespace AZ
void CpuProfilerImpl::Init()
{
Interface<AZ::Debug::Profiler>::Register(this);
Interface<CpuProfiler>::Register(this);
m_initialized = true;
SystemTickBus::Handler::BusConnect();
@@ -106,6 +83,7 @@ namespace AZ
}
// When this call is made, no more thread profiling calls can be performed anymore
Interface<CpuProfiler>::Unregister(this);
Interface<AZ::Debug::Profiler>::Unregister(this);
// Wait for the remaining threads that might still be processing its profiling calls
AZStd::unique_lock<AZStd::shared_mutex> shutdownLock(m_shutdownMutex);
@@ -121,7 +99,7 @@ namespace AZ
SystemTickBus::Handler::BusDisconnect();
}
void CpuProfilerImpl::BeginTimeRegion(TimeRegion& timeRegion)
void CpuProfilerImpl::BeginRegion(const AZ::Debug::Budget* budget, const char* eventName)
{
// Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
if (m_shutdownMutex.try_lock_shared())
@@ -132,6 +110,7 @@ namespace AZ
RegisterThreadStorage();
// Push it to the stack
CachedTimeRegion timeRegion({budget->Name(), eventName});
ms_threadLocalStorage->RegionStackPushBack(timeRegion);
}
@@ -139,11 +118,12 @@ namespace AZ
}
}
void CpuProfilerImpl::EndTimeRegion()
void CpuProfilerImpl::EndRegion([[maybe_unused]] const AZ::Debug::Budget* budget)
{
// Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
if (m_shutdownMutex.try_lock_shared())
{
// guard against enabling mid-marker
if (m_enabled && ms_threadLocalStorage != nullptr)
{
ms_threadLocalStorage->RegionStackPopBack();
@@ -232,19 +212,6 @@ namespace AZ
return m_enabled;
}
const CachedTimeRegion::GroupRegionName& CpuProfilerImpl::InsertDynamicName(const char* groupName, const AZStd::string& regionName)
{
AZStd::scoped_lock lock(m_dynamicNameMutex);
AZ_Warning("CpuProfiler", m_regionNameStringPool.size() < MaxRegionStringPoolSize,
"Stored dynamic region names are accumulating. Consider removing a AZ_ATOM_PROFILE_DYNAMIC invocation.");
auto [regionNameItr, wasRegionInserted] = m_regionNameStringPool.insert(regionName);
CachedTimeRegion::GroupRegionName newGroupRegionName(groupName, regionNameItr->c_str());
auto [groupRegionNameItr, wasGroupRegionInserted] = m_dynamicGroupRegionNamePool.insert(newGroupRegionName);
return *groupRegionNameItr;
}
void CpuProfilerImpl::OnSystemTick()
{
if (!m_enabled)
@@ -307,7 +274,7 @@ namespace AZ
m_deleteFlag = true;
}
void CpuTimingLocalStorage::RegionStackPushBack(TimeRegion& timeRegion)
void CpuTimingLocalStorage::RegionStackPushBack(CachedTimeRegion& timeRegion)
{
// If it was (re)enabled, clear the lists first
if (m_clearContainers)
@@ -323,13 +290,13 @@ namespace AZ
timeRegion.m_stackDepth = static_cast<uint16_t>(m_stackLevel);
AZ_Assert(m_timeRegionStack.size() < TimeRegionStackSize, "Adding too many time regions to the stack. Increase the size of TimeRegionStackSize.");
m_timeRegionStack.push_back(&timeRegion);
m_timeRegionStack.push_back(timeRegion);
// Increment the stack
m_stackLevel++;
// Set the starting time at the end, to avoid recording the minor overhead
timeRegion.m_startTick = AZStd::GetTimeNowTicks();
m_timeRegionStack.back().m_startTick = AZStd::GetTimeNowTicks();
}
void CpuTimingLocalStorage::RegionStackPopBack()
@@ -344,23 +311,23 @@ namespace AZ
const AZStd::sys_time_t endRegionTime = AZStd::GetTimeNowTicks();
AZ_Assert(!m_timeRegionStack.empty(), "Trying to pop an element in the stack, but it's empty.");
TimeRegion* back = m_timeRegionStack.back();
CachedTimeRegion back = m_timeRegionStack.back();
m_timeRegionStack.pop_back();
// Set the ending time
back->m_endTick = endRegionTime;
back.m_endTick = endRegionTime;
// Decrement the stack
m_stackLevel--;
// Add an entry to the cached region
AddCachedRegion(CachedTimeRegion(back->m_groupRegionName, back->m_stackDepth, back->m_startTick, back->m_endTick));
AddCachedRegion(back);
}
// Gets called when region ends and all data is set
void CpuTimingLocalStorage::AddCachedRegion(CachedTimeRegion&& timeRegionCached)
void CpuTimingLocalStorage::AddCachedRegion(const CachedTimeRegion& timeRegionCached)
{
if (m_hitSizeLimitMap[timeRegionCached.m_groupRegionName->m_regionName])
if (m_hitSizeLimitMap[timeRegionCached.m_groupRegionName.m_regionName])
{
return;
}
@@ -379,12 +346,12 @@ namespace AZ
// Add the cached regions to the map
for (auto& cachedTimeRegion : m_cachedTimeRegions)
{
const AZStd::string regionName = cachedTimeRegion.m_groupRegionName->m_regionName;
const AZStd::string regionName = cachedTimeRegion.m_groupRegionName.m_regionName;
AZStd::vector<CachedTimeRegion>& regionVec = m_cachedTimeRegionMap[regionName];
regionVec.push_back(cachedTimeRegion);
if (regionVec.size() >= TimeRegionStackSize)
{
m_hitSizeLimitMap[cachedTimeRegion.m_groupRegionName->m_regionName] = true;
m_hitSizeLimitMap.insert_or_assign(AZStd::move(regionName), true);
}
}
@@ -448,8 +415,8 @@ namespace AZ
CpuProfilingStatisticsSerializer::CpuProfilingStatisticsSerializerEntry::CpuProfilingStatisticsSerializerEntry(
const RHI::CachedTimeRegion& cachedTimeRegion, AZStd::thread_id threadId)
{
m_groupName = cachedTimeRegion.m_groupRegionName->m_groupName;
m_regionName = cachedTimeRegion.m_groupRegionName->m_regionName;
m_groupName = cachedTimeRegion.m_groupRegionName.m_groupName;
m_regionName = cachedTimeRegion.m_groupRegionName.m_regionName;
m_stackDepth = cachedTimeRegion.m_stackDepth;
m_startTick = cachedTimeRegion.m_startTick;
m_endTick = cachedTimeRegion.m_endTick;
+2 -2
View File
@@ -128,7 +128,7 @@ namespace AZ
{
if (ValidateIsInitialized() && ValidateIsInFrame())
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "Device: EndFrame");
AZ_PROFILE_SCOPE(RHI, "Device: EndFrame");
EndFrameInternal();
m_isInFrame = false;
return ResultCode::Success;
@@ -150,7 +150,7 @@ namespace AZ
{
if (ValidateIsInitialized() && ValidateIsNotInFrame())
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "Device: CompileMemoryStatistics");
AZ_PROFILE_SCOPE(RHI, "Device: CompileMemoryStatistics");
MemoryStatisticsBuilder builder;
builder.Begin(memoryStatistics, reportFlags);
CompileMemoryStatisticsInternal(builder);
+1 -1
View File
@@ -81,7 +81,7 @@ namespace AZ
return ResultCode::InvalidOperation;
}
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "Fence: WaitOnCpu");
WaitOnCpuInternal();
return ResultCode::Success;
}
+2 -2
View File
@@ -73,7 +73,7 @@ namespace AZ
void FrameGraph::Clear()
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraph: Clear");
AZ_PROFILE_SCOPE(RHI, "FrameGraph: Clear");
for (Scope* scope : m_scopes)
{
scope->Deactivate();
@@ -126,7 +126,7 @@ namespace AZ
ResultCode FrameGraph::End()
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraph: End");
AZ_PROFILE_SCOPE(RHI, "FrameGraph: End");
ResultCode resultCode = ValidateEnd();
if (resultCode != ResultCode::Success)
{
@@ -121,7 +121,7 @@ namespace AZ
*/
MessageOutcome FrameGraphCompiler::Compile(const FrameGraphCompileRequest& request)
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: Compile");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: Compile");
MessageOutcome outcome = ValidateCompileRequest(request);
if (!outcome)
@@ -146,7 +146,7 @@ namespace AZ
/// [Phase 4] Compile platform-specific scope data after all attachments and views have been compiled.
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: Scope Compile");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: Scope Compile");
for (Scope* scope : frameGraph.GetScopes())
{
@@ -162,7 +162,7 @@ namespace AZ
FrameGraph& frameGraph,
FrameSchedulerCompileFlags compileFlags)
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: CompileQueueCentricScopeGraph");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: CompileQueueCentricScopeGraph");
const bool disableAsyncQueues = CheckBitsAll(compileFlags, FrameSchedulerCompileFlags::DisableAsyncQueues);
if (disableAsyncQueues)
@@ -480,7 +480,7 @@ namespace AZ
return;
}
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: CompileTransientAttachments");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: CompileTransientAttachments");
ExtendTransientAttachmentAsyncQueueLifetimes(frameGraph, compileFlags);
@@ -769,7 +769,7 @@ namespace AZ
void FrameGraphCompiler::CompileResourceViews(const FrameGraphAttachmentDatabase& attachmentDatabase)
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: CompileResourceViews");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: CompileResourceViews");
for (ImageFrameAttachment* imageAttachment : attachmentDatabase.GetImageAttachments())
{
@@ -71,14 +71,13 @@ namespace AZ
void FrameGraphExecuter::Begin(const FrameGraph& frameGraph)
{
AZ_TRACE_METHOD();
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphExecuter: Begin");
AZ_PROFILE_SCOPE(RHI, "FrameGraphExecuter: Begin");
BeginInternal(frameGraph);
}
void FrameGraphExecuter::End()
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphExecuter: End");
AZ_PROFILE_SCOPE(RHI, "FrameGraphExecuter: End");
AZ_Assert(m_pendingGroups.empty(), "Pending contexts in queue.");
m_groups.clear();
EndInternal();
@@ -137,7 +137,7 @@ namespace AZ
ResultCode FrameScheduler::ImportScopeProducer(ScopeProducer& scopeProducer)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: ImportScopeProducer");
if (!ValidateIsProcessing())
{
@@ -171,14 +171,14 @@ namespace AZ
MessageOutcome FrameScheduler::Compile(const FrameSchedulerCompileRequest& compileRequest)
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameScheduler: Compile");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: Compile");
PrepareProducers();
m_compileRequest = compileRequest;
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RHI", "FrameScheduler: Compile: OnFrameCompile");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: Compile: OnFrameCompile");
FrameEventBus::Broadcast(&FrameEventBus::Events::OnFrameCompile);
}
@@ -193,7 +193,7 @@ namespace AZ
if (outcome.IsSuccess())
{
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RHI", "FrameScheduler: Compile: OnFrameCompileEnd");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: Compile: OnFrameCompileEnd");
FrameEventBus::Broadcast(&FrameEventBus::Events::OnFrameCompileEnd, *m_frameGraph);
}
@@ -216,8 +216,7 @@ namespace AZ
void FrameScheduler::PrepareProducers()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameScheduler: PrepareProducers");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: PrepareProducers");
for (ScopeProducer* scopeProducer : m_scopeProducers)
{
@@ -237,8 +236,7 @@ namespace AZ
void FrameScheduler::CompileProducers()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameScheduler: CompileProducers");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: CompileProducers");
for (ScopeProducer* scopeProducer : m_scopeProducers)
{
@@ -249,8 +247,7 @@ namespace AZ
void FrameScheduler::CompileShaderResourceGroups()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameScheduler: CompileShaderResourceGroups");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: CompileShaderResourceGroups");
// Execute all queued resource invalidations, which will mark SRG's for compilation.
{
@@ -286,7 +283,7 @@ namespace AZ
const auto compileGroupsForIntervalLambda = [srgPool, interval]()
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameScheduler : compileGroupsForIntervalLambda");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler : compileGroupsForIntervalLambda");
srgPool->CompileGroupsForInterval(interval);
};
@@ -322,8 +319,7 @@ namespace AZ
void FrameScheduler::BuildRayTracingShaderTables()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameScheduler: BuildRayTracingShaderTables");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: BuildRayTracingShaderTables");
for (auto rayTracingShaderTable : m_rayTracingShaderTablesToBuild)
{
@@ -341,8 +337,7 @@ namespace AZ
ResultCode FrameScheduler::BeginFrame()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameScheduler: BeginFrame");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: BeginFrame");
if (!ValidateIsInitialized())
{
@@ -376,8 +371,7 @@ namespace AZ
ResultCode FrameScheduler::EndFrame()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameScheduler: EndFrame");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: EndFrame");
if (Validation::IsEnabled())
{
@@ -404,7 +398,7 @@ namespace AZ
m_scopeProducerLookup.clear();
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RHI", "FrameScheduler: EndFrame: OnFrameEnd");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: EndFrame: OnFrameEnd");
FrameEventBus::Event(m_device, &FrameEventBus::Events::OnFrameEnd);
}
@@ -431,8 +425,7 @@ namespace AZ
void FrameScheduler::ExecuteGroupInternal(AZ::Job* parentJob, uint32_t groupIndex)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameScheduler: ExecuteGroupInternal");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: ExecuteGroupInternal");
FrameGraphExecuteGroup* executeGroup = m_frameGraphExecuter->BeginGroup(groupIndex);
const uint32_t contextCount = executeGroup->GetContextCount();
@@ -474,8 +467,7 @@ namespace AZ
void FrameScheduler::Execute(JobPolicy overrideJobPolicy)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameScheduler: Execute");
AZ_PROFILE_SCOPE(RHI, "FrameScheduler: Execute");
const uint32_t groupCount = m_frameGraphExecuter->GetGroupCount();
const JobPolicy platformJobPolicy = m_frameGraphExecuter->GetJobPolicy();
@@ -212,7 +212,7 @@ namespace AZ
void PipelineStateCache::Compact()
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "PipelineStateCache: Compact");
AZ_PROFILE_SCOPE(RHI, "PipelineStateCache: Compact");
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
// Merge the pending cache into the read-only cache.
+2 -3
View File
@@ -187,8 +187,7 @@ namespace AZ
void RHISystem::FrameUpdate(FrameGraphCallback frameGraphCallback)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_ATOM_PROFILE_FUNCTION("RHI", "RHISystem: FrameUpdate");
AZ_PROFILE_SCOPE(RHI, "RHISystem: FrameUpdate");
{
AZ_PROFILE_SCOPE(RHI, "main per-frame work");
@@ -201,7 +200,7 @@ namespace AZ
* own RHI scopes to the frame scheduler. This happens prior to the RPI pass graph registration.
*/
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RHI", "RHISystem: FrameUpdate: OnFramePrepare");
AZ_PROFILE_SCOPE(RHI, "RHISystem: FrameUpdate: OnFramePrepare");
RHISystemNotificationBus::Broadcast(&RHISystemNotificationBus::Events::OnFramePrepare, m_frameScheduler);
}
@@ -196,7 +196,7 @@ namespace AZ
AsyncUploadQueue::FramePacket* AsyncUploadQueue::BeginFramePacket()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "AsyncUploadQueue: BeginFramePacket");
AZ_Assert(!m_recordingFrame, "The previous frame packet isn't ended");
FramePacket* framePacket = &m_framePackets[m_frameIndex];
@@ -212,7 +212,7 @@ namespace AZ
void AsyncUploadQueue::EndFramePacket(ID3D12CommandQueue* commandQueue)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "AsyncUploadQueue: EndFramePacket");
AZ_Assert(m_recordingFrame, "The frame packet wasn't started. You need to call StartFramePacket first.");
AssertSuccess(m_commandList->Close());
@@ -229,7 +229,7 @@ namespace AZ
// [GFX TODO][ATOM-4205] Stage/Upload 3D streaming images more efficiently.
uint64_t AsyncUploadQueue::QueueUpload(const RHI::StreamingImageExpandRequest& request, uint32_t residentMip)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "AsyncUploadQueue: QueueUpload");
uint64_t fenceValue = m_uploadFence.Increment();
@@ -475,7 +475,7 @@ namespace AZ
void AsyncUploadQueue::WaitForUpload(uint64_t fenceValue)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "AsyncUploadQueue: WaitForUpload");
if (!IsUploadFinished(fenceValue))
{
@@ -489,7 +489,7 @@ namespace AZ
void AsyncUploadQueue::ProcessCallbacks(uint64_t fenceValue)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "AsyncUploadQueue: ProcessCallbacks");
AZStd::lock_guard<AZStd::mutex> lock(m_callbackMutex);
while (m_callbacks.size() > 0 && m_callbacks.front().second <= fenceValue)
{
@@ -33,7 +33,7 @@ namespace AZ
void CommandListBase::Reset(ID3D12CommandAllocator* commandAllocator)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "CommandListBase: Reset");
AZ_Assert(m_queuedBarriers.empty(), "Unflushed barriers in command list.");
m_commandList->Reset(commandAllocator, nullptr);
@@ -95,7 +95,7 @@ namespace AZ
{
if (m_queuedBarriers.size())
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "CommandListBase: FlushBarriers");
m_commandList->ResourceBarrier((UINT)m_queuedBarriers.size(), m_queuedBarriers.data());
m_queuedBarriers.clear();
@@ -175,7 +175,7 @@ namespace AZ
void CommandListAllocator::Collect()
{
AZ_ATOM_PROFILE_FUNCTION("DX12", "CommandListAllocator: Collect");
AZ_PROFILE_SCOPE(RHI, "CommandListAllocator: Collect(DX12)");
for (uint32_t queueIdx = 0; queueIdx < RHI::HardwareQueueClassCount; ++queueIdx)
{
m_commandListSubAllocators[queueIdx].ForEach([](Internal::CommandListSubAllocator& commandListSubAllocator)
@@ -195,7 +195,7 @@ namespace AZ
void CommandQueue::UpdateTileMappings(CommandList& commandList)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "CommandQueue: UpdateTileMappings");
for (const CommandList::TileMapRequest& request : commandList.GetTileMapRequests())
{
const uint32_t tileCount = request.m_sourceRegionSize.NumTiles;
@@ -229,7 +229,7 @@ namespace AZ
void CommandQueue::WaitForIdle()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "CommandQueue: WaitForIdle");
Fence fence;
fence.Init(m_device.get(), RHI::FenceState::Reset);
@@ -101,7 +101,7 @@ namespace AZ
void CommandQueueContext::WaitForIdle()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "CommandQueueContext: WaitForIdle");
for (uint32_t hardwareQueueIdx = 0; hardwareQueueIdx < RHI::HardwareQueueClassCount; ++hardwareQueueIdx)
{
if (m_commandQueues[hardwareQueueIdx])
@@ -113,7 +113,7 @@ namespace AZ
void CommandQueueContext::Begin()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "CommandQueueContext: Begin");
{
AZ_PROFILE_SCOPE(RHI, "Clearing Command Queue Timers");
@@ -131,8 +131,7 @@ namespace AZ
void CommandQueueContext::End()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_ATOM_PROFILE_FUNCTION("DX12", "CommandQueueContext: End");
AZ_PROFILE_SCOPE(RHI, "CommandQueueContext: End");
QueueGpuSignals(m_frameFences[m_currentFrameIndex]);
@@ -146,7 +145,6 @@ namespace AZ
{
AZ_PROFILE_SCOPE(RHI, "Wait and Reset Fence");
AZ_ATOM_PROFILE_TIME_GROUP_REGION("DX12", "CommandQueueContext: Wait on Fences");
FenceEvent event("FrameFence");
m_frameFences[m_currentFrameIndex].Wait(event);
@@ -341,7 +341,7 @@ namespace AZ
void DescriptorContext::GarbageCollect()
{
AZ_ATOM_PROFILE_FUNCTION("DX12", "DescriptorContext: GarbageCollect");
AZ_PROFILE_SCOPE(RHI, "DescriptorContext: GarbageCollect(DX12)");
for (const auto& itr : m_platformLimitsDescriptor->m_descriptorHeapLimits)
{
for (uint32_t shaderVisibleIdx = 0; shaderVisibleIdx < PlatformLimitsDescriptor::NumHeapFlags; ++shaderVisibleIdx)
@@ -204,7 +204,7 @@ namespace AZ
RHI::MessageOutcome FrameGraphCompiler::CompileInternal(const RHI::FrameGraphCompileRequest& request)
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: CompileInternal(DX12)");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: CompileInternal(DX12)");
RHI::FrameGraph& frameGraph = *request.m_frameGraph;
@@ -373,7 +373,7 @@ namespace AZ
void FrameGraphCompiler::CompileResourceBarriers(Scope* rootScope, const RHI::FrameGraphAttachmentDatabase& attachmentDatabase)
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: CompileResourceBarriers(DX12)");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: CompileResourceBarriers(DX12)");
for (RHI::BufferFrameAttachment* bufferFrameAttachment : attachmentDatabase.GetBufferAttachments())
{
@@ -394,7 +394,7 @@ namespace AZ
ResourceTransitionLoggerNull logger(bufferFrameAttachment.GetId());
#endif
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: CompileBufferBarriers(DX12)");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: CompileBufferBarriers(DX12)");
Buffer& buffer = static_cast<Buffer&>(*bufferFrameAttachment.GetBuffer());
RHI::BufferScopeAttachment* scopeAttachment = bufferFrameAttachment.GetFirstScopeAttachment();
@@ -469,7 +469,7 @@ namespace AZ
ResourceTransitionLoggerNull logger(imageFrameAttachment.GetId());
#endif
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: CompileImageBarriers (DX12)");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: CompileImageBarriers (DX12)");
Image& image = static_cast<Image&>(*imageFrameAttachment.GetImage());
RHI::ImageScopeAttachment* scopeAttachment = imageFrameAttachment.GetFirstScopeAttachment();
@@ -55,7 +55,7 @@ namespace AZ
void StagingMemoryAllocator::GarbageCollect()
{
AZ_ATOM_PROFILE_FUNCTION("DX12", "StagingMemoryAllocator: GarbageCollect");
AZ_PROFILE_SCOPE(RHI, "StagingMemoryAllocator: GarbageCollect(DX12)");
m_mediumBlockAllocators.ForEach([](MemoryLinearSubAllocator& subAllocator)
{
subAllocator.GarbageCollect();
@@ -79,8 +79,8 @@ namespace AZ
void CommandQueueContext::End()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "CommandQueueContext: End");
QueueGpuSignals(m_frameFences[m_currentFrameIndex]);
for (uint32_t hardwareQueueIdx = 0; hardwareQueueIdx < RHI::HardwareQueueClassCount; ++hardwareQueueIdx)
{
@@ -92,7 +92,6 @@ namespace AZ
{
AZ_PROFILE_SCOPE(RHI, "Wait and Reset Fence");
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RHI", "CommandQueueContext: Wait on Fences");
//Synchronize the CPU with the GPU by waiting on the fence until signalled by the GPU. CPU can only go upto
//RHI::Limits::Device::FrameCountMax frames ahead of the GPU
@@ -33,7 +33,7 @@ namespace AZ
RHI::MessageOutcome FrameGraphCompiler::CompileInternal(const RHI::FrameGraphCompileRequest& request)
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: CompileInternal(Metal)");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: CompileInternal(Metal)");
RHI::FrameGraph& frameGraph = *request.m_frameGraph;
if (!RHI::CheckBitsAny(request.m_compileFlags, RHI::FrameSchedulerCompileFlags::DisableAsyncQueues))
{
@@ -192,7 +192,7 @@ namespace AZ
id<MTLTexture> SwapChain::RequestDrawable(bool isFrameCaptureEnabled)
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "SwapChain::RequestDrawable");
AZ_PROFILE_SCOPE(RHI, "SwapChain::RequestDrawable");
m_metalView.metalLayer.framebufferOnly = !isFrameCaptureEnabled;
const uint32_t currentImageIndex = GetCurrentImageIndex();
if(m_drawables[currentImageIndex])
@@ -451,7 +451,7 @@ namespace AZ
AsyncUploadQueue::FramePacket* AsyncUploadQueue::BeginFramePacket(Queue* queue)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "AsyncUploadQueue: BeginFramePacket");
AZ_Assert(!m_recordingFrame, "The previous frame packet isn't ended.");
auto& device = static_cast<Device&>(GetDevice());
@@ -471,7 +471,7 @@ namespace AZ
void AsyncUploadQueue::EndFramePacket(Queue* queue, Semaphore* semaphoreToSignal /*=nullptr*/)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "AsyncUploadQueue: EndFramePacket");
AZ_Assert(m_recordingFrame, "The frame packet wasn't started. You need to call StartFramePacket first.");
m_commandList->EndCommandBuffer();
@@ -636,7 +636,7 @@ namespace AZ
void AsyncUploadQueue::ProcessCallback(const RHI::AsyncWorkHandle& handle)
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "AsyncUploadQueue: ProcessCallback");
AZStd::unique_lock<AZStd::mutex> lock(m_callbackListMutex);
auto findIter = m_callbackList.find(handle);
if (findIter != m_callbackList.end())
@@ -42,7 +42,7 @@ namespace AZ
void CommandQueueContext::End()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "CommandQueueContext: End");
for (auto& commandQueue : m_commandQueues)
{
@@ -55,7 +55,6 @@ namespace AZ
{
AZ_PROFILE_SCOPE(RHI, "Wait on Fences");
AZ_ATOM_PROFILE_FUNCTION("RHI", "CommandQueueContext: Wait on Fences");
FencesPerQueue& nextFences = m_frameFences[m_currentFrameIndex];
for (auto& fence : nextFences)
@@ -79,7 +78,7 @@ namespace AZ
void CommandQueueContext::WaitForIdle()
{
AZ_PROFILE_FUNCTION(RHI);
AZ_PROFILE_SCOPE(RHI, "CommandQueueContext: WaitForIdle");
for (auto& commandQueue : m_commandQueues)
{
commandQueue->WaitForIdle();
@@ -45,7 +45,7 @@ namespace AZ
RHI::MessageOutcome FrameGraphCompiler::CompileInternal(const RHI::FrameGraphCompileRequest& request)
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: CompileInternal(Vulkan)");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: CompileInternal(Vulkan)");
AZ_Assert(request.m_frameGraph, "FrameGraph is null.");
RHI::FrameGraph& frameGraph = *request.m_frameGraph;
@@ -89,7 +89,7 @@ namespace AZ
void FrameGraphCompiler::CompileResourceBarriers(const RHI::FrameGraphAttachmentDatabase& attachmentDatabase)
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "FrameGraphCompiler: CompileResourceBarriers(Vulkan)");
AZ_PROFILE_SCOPE(RHI, "FrameGraphCompiler: CompileResourceBarriers(Vulkan)");
for (RHI::BufferFrameAttachment* bufferFrameAttachment : attachmentDatabase.GetBufferAttachments())
{
@@ -299,7 +299,7 @@ namespace AZ
//work function
void Process() override
{
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "AddObjectsToViewJob: Process");
const View::UsageFlags viewFlags = m_jobData->m_view->GetUsageFlags();
const RHI::DrawListMask drawListMask = m_jobData->m_view->GetDrawListMask();
@@ -645,7 +645,7 @@ namespace AZ
uint32_t AddLodDataToView(const Vector3& pos, const Cullable::LodData& lodData, RPI::View& view)
{
#ifdef AZ_CULL_PROFILE_DETAILED
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "AddLodDataToView");
#endif
const Matrix4x4& viewToClip = view.GetViewToClipMatrix();
@@ -725,7 +725,7 @@ namespace AZ
void CullingScene::BeginCulling(const AZStd::vector<ViewPtr>& views)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "CullingScene: BeginCulling");
AZ_PROFILE_SCOPE(RPI, "CullingScene: BeginCulling");
m_cullDataConcurrencyCheck.soft_lock();
m_debugCtx.ResetCullStats();
@@ -75,7 +75,7 @@ namespace AZ
void GpuQuerySystem::Update()
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "GpuQuerySystem: Update");
AZ_PROFILE_SCOPE(RPI, "GpuQuerySystem: Update");
for (auto& queryPool : m_queryPoolArray)
{
if (queryPool)
@@ -34,6 +34,8 @@
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Math/Color.h>
AZ_DECLARE_BUDGET(RPI);
namespace AZ
{
namespace RPI
@@ -171,7 +173,7 @@ namespace AZ
void ImageSystem::Update()
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "ImageSystem: Update");
AZ_PROFILE_SCOPE(RPI, "ImageSystem: Update");
AZStd::lock_guard<AZStd::mutex> lock(m_activeStreamingPoolMutex);
for (StreamingImagePool* imagePool : m_activeStreamingPools)
@@ -42,7 +42,7 @@ namespace AZ
Data::Instance<Model> Model::CreateInternal(const Data::Asset<ModelAsset>& modelAsset)
{
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "Model: CreateInternal");
Data::Instance<Model> model = aznew Model();
const RHI::ResultCode resultCode = model->Init(modelAsset);
@@ -56,7 +56,7 @@ namespace AZ
RHI::ResultCode Model::Init(const Data::Asset<ModelAsset>& modelAsset)
{
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "Model: Init");
m_lods.resize(modelAsset->GetLodAssets().size());
@@ -128,7 +128,7 @@ namespace AZ
bool Model::LocalRayIntersection(const AZ::Vector3& rayStart, const AZ::Vector3& rayDir, float& distanceNormalized, AZ::Vector3& normal) const
{
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "Model: LocalRayIntersection");
if (!GetModelAsset())
{
@@ -171,7 +171,7 @@ namespace AZ
float& distanceNormalized,
AZ::Vector3& normal) const
{
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "Model: RayIntersection");
const AZ::Vector3 clampedScale = nonUniformScale.GetMax(AZ::Vector3(AZ::MinTransformScale));
const AZ::Transform inverseTM = modelTransform.GetInverse();
@@ -27,7 +27,7 @@ namespace AZ
ModelLodIndex SelectLod(const View* view, const Vector3& position, const Model& model, ModelLodIndex lodOverride)
{
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "ModelLodUtils: SelectLod");
ModelLodIndex lodIndex;
if (model.GetLodCount() == 1)
{
@@ -169,7 +169,7 @@ namespace AZ
void PassSystem::RemovePasses()
{
m_state = PassSystemState::RemovingPasses;
AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: RemovePasses");
AZ_PROFILE_SCOPE(RPI, "PassSystem: RemovePasses");
if (!m_removePassList.empty())
{
@@ -189,8 +189,7 @@ namespace AZ
void PassSystem::BuildPasses()
{
m_state = PassSystemState::BuildingPasses;
AZ_PROFILE_FUNCTION(RPI);
AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: BuildPassAttachments");
AZ_PROFILE_SCOPE(RPI, "PassSystem: BuildPasses");
m_passHierarchyChanged = m_passHierarchyChanged || !m_buildPassList.empty();
@@ -239,8 +238,7 @@ namespace AZ
void PassSystem::InitializePasses()
{
m_state = PassSystemState::InitializingPasses;
AZ_PROFILE_FUNCTION(RPI);
AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: BuildPassAttachments");
AZ_PROFILE_SCOPE(RPI, "PassSystem: InitializePasses");
m_passHierarchyChanged = m_passHierarchyChanged || !m_initializePassList.empty();
@@ -277,7 +275,6 @@ namespace AZ
void PassSystem::Validate()
{
m_state = PassSystemState::ValidatingPasses;
AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: Validate");
if (PassValidation::IsEnabled())
{
@@ -286,7 +283,7 @@ namespace AZ
return;
}
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "PassSystem: Validate");
PassValidationResults validationResults;
m_rootPass->Validate(validationResults);
@@ -298,7 +295,7 @@ namespace AZ
void PassSystem::ProcessQueuedChanges()
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: ProcessQueuedChanges");
AZ_PROFILE_SCOPE(RPI, "PassSystem: ProcessQueuedChanges");
RemovePasses();
BuildPasses();
InitializePasses();
@@ -307,8 +304,7 @@ namespace AZ
void PassSystem::FrameUpdate(RHI::FrameGraphBuilder& frameGraphBuilder)
{
AZ_PROFILE_FUNCTION(RPI);
AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: FrameUpdate");
AZ_PROFILE_SCOPE(RPI, "PassSystem: FrameUpdate");
ResetFrameStatistics();
ProcessQueuedChanges();
@@ -317,14 +313,14 @@ namespace AZ
Pass::FramePrepareParams params{ &frameGraphBuilder };
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "Pass: FrameBegin");
AZ_PROFILE_SCOPE(RPI, "Pass: FrameBegin");
m_rootPass->FrameBegin(params);
}
}
void PassSystem::FrameEnd()
{
AZ_ATOM_PROFILE_FUNCTION("RHI", "PassSystem: FrameEnd");
AZ_PROFILE_SCOPE(RHI, "PassSystem: FrameEnd");
m_state = PassSystemState::FrameEnd;
@@ -216,7 +216,7 @@ namespace AZ
void RasterPass::CompileResources(const RHI::FrameGraphCompileContext& context)
{
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "RasterPass: CompileResources");
if (m_shaderResourceGroup == nullptr)
{
@@ -233,7 +233,7 @@ namespace AZ
void RPISystem::OnSystemTick()
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "RPISystem: OnSystemTick");
AZ_PROFILE_SCOPE(RPI, "RPISystem: OnSystemTick");
// Image system update is using system tick but not game tick so it can stream images in background even game is pausing
m_imageSystem.Update();
@@ -245,7 +245,7 @@ namespace AZ
{
return;
}
AZ_ATOM_PROFILE_FUNCTION("RPI", "RPISystem: SimulationTick");
AZ_PROFILE_SCOPE(RPI, "RPISystem: SimulationTick");
AssetInitBus::Broadcast(&AssetInitBus::Events::PostLoadInit);
@@ -273,8 +273,7 @@ namespace AZ
return;
}
AZ_PROFILE_FUNCTION(RPI);
AZ_ATOM_PROFILE_FUNCTION("RPI", "RPISystem: RenderTick");
AZ_PROFILE_SCOPE(RPI, "RPISystem: RenderTick");
// Query system update is to increment the frame count
m_querySystem.Update();
@@ -301,7 +300,7 @@ namespace AZ
});
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "RPISystem: FrameEnd");
AZ_PROFILE_SCOPE(RPI, "RPISystem: FrameEnd");
m_dynamicDraw.FrameEnd();
m_passSystem.FrameEnd();
@@ -397,7 +397,7 @@ namespace AZ
void RenderPipeline::OnStartFrame()
{
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "RenderPipeline: OnStartFrame");
m_lastRenderStartTime = m_lastRenderRequestTime;
+11 -14
View File
@@ -350,7 +350,7 @@ namespace AZ
void Scene::Simulate([[maybe_unused]] const TickTimeInfo& tickInfo, RHI::JobPolicy jobPolicy)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "Scene: Simulate");
AZ_PROFILE_SCOPE(RPI, "Scene: Simulate");
m_simulationTime = tickInfo.m_currentGameTime;
@@ -389,7 +389,7 @@ namespace AZ
{
if (completionJob)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "Scene: WaitAndCleanCompletionJob");
AZ_PROFILE_SCOPE(RPI, "Scene: WaitAndCleanCompletionJob");
//[GFX TODO]: the completion job should start earlier and wait for completion here
completionJob->StartAndWaitForCompletion();
delete completionJob;
@@ -422,11 +422,10 @@ namespace AZ
void Scene::PrepareRender([[maybe_unused]]const TickTimeInfo& tickInfo, RHI::JobPolicy jobPolicy)
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "Scene: PrepareRender");
AZ_PROFILE_SCOPE(RPI, "Scene: PrepareRender");
{
AZ_PROFILE_SCOPE(RPI, "WaitForSimulationCompletion");
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "WaitForSimulationCompletion");
WaitAndCleanCompletionJob(m_simulationCompletion);
}
@@ -435,7 +434,7 @@ namespace AZ
// Get active pipelines which need to be rendered and notify them of an impending frame.
AZStd::vector<RenderPipelinePtr> activePipelines;
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "Scene: OnPrepareFrame");
AZ_PROFILE_SCOPE(RPI, "Scene: OnPrepareFrame");
for (auto& pipeline : m_pipelines)
{
pipeline->OnPrepareFrame();
@@ -449,7 +448,7 @@ namespace AZ
// Get active pipelines which need to be rendered and notify them frame started
for (const auto& pipeline : activePipelines)
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "Scene: OnStartFrame");
AZ_PROFILE_SCOPE(RPI, "Scene: OnStartFrame");
pipeline->OnStartFrame();
}
@@ -468,7 +467,7 @@ namespace AZ
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "Setup Views");
AZ_PROFILE_SCOPE(RPI, "Setup Views");
// Collect persistent views from all pipelines to be rendered
AZStd::map<ViewPtr, RHI::DrawListMask> persistentViews;
@@ -506,8 +505,7 @@ namespace AZ
}
{
AZ_PROFILE_SCOPE(RPI, "CollectDrawPackets");
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "CollectDrawPackets");
AZ_PROFILE_SCOPE(RPI, "CollectDrawPackets");
AZ::JobCompletion* collectDrawPacketsCompletion = aznew AZ::JobCompletion();
// Launch FeatureProcessor::Render() jobs
@@ -550,14 +548,13 @@ namespace AZ
// Add dynamic draw data for all the views
if (m_dynamicDrawSystem)
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "DynamicDraw SubmitDrawData");
AZ_PROFILE_SCOPE(RPI, "DynamicDraw SubmitDrawData");
m_dynamicDrawSystem->SubmitDrawData(this, m_renderPacket.m_views);
}
}
{
AZ_PROFILE_BEGIN(RPI, "FinalizeDrawLists");
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "FinalizeDrawLists");
if (jobPolicy == RHI::JobPolicy::Serial)
{
for (auto& view : m_renderPacket.m_views)
@@ -586,14 +583,14 @@ namespace AZ
}
{
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "Scene OnEndPrepareRender");
AZ_PROFILE_SCOPE(RPI, "Scene OnEndPrepareRender");
SceneNotificationBus::Event(GetId(), &SceneNotification::OnEndPrepareRender);
}
}
void Scene::OnFrameEnd()
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "Scene: OnFrameEnd");
AZ_PROFILE_SCOPE(RPI, "Scene: OnFrameEnd");
bool didRender = false;
for (auto& pipeline : m_pipelines)
{
@@ -730,7 +727,7 @@ namespace AZ
void Scene::RebuildPipelineStatesLookup()
{
AZ_ATOM_PROFILE_FUNCTION("RPI", "Scene: RebuildPipelineStatesLookup");
AZ_PROFILE_SCOPE(RPI, "Scene: RebuildPipelineStatesLookup");
m_pipelineStatesLookup.clear();
AZStd::queue<ParentPass*> parents;
@@ -113,7 +113,7 @@ namespace AZ
return;
}
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "ShaderMetricsSystem: RequestShaderVariant");
AZStd::lock_guard<AZStd::mutex> lock(m_metricsMutex);
@@ -239,7 +239,7 @@ namespace AZ
void View::FinalizeDrawLists()
{
AZ_PROFILE_FUNCTION(RPI);
AZ_PROFILE_SCOPE(RPI, "View: FinalizeDrawLists");
m_drawListContext.FinalizeLists();
if (m_passesByDrawList)
{
@@ -174,7 +174,7 @@ namespace AZ
AZStd::unordered_map<size_t, AZStd::vector<TimeRegion>> m_savedData;
// Region color cache
AZStd::unordered_map<const GroupRegionName*, ImVec4> m_regionColorMap;
AZStd::unordered_map<GroupRegionName, ImVec4, RHI::CachedTimeRegion::GroupRegionName::Hash> m_regionColorMap;
// Tracks the frame boundaries
AZStd::vector<AZStd::sys_time_t> m_frameEndTicks = { INT64_MIN };
@@ -124,7 +124,7 @@ namespace AZ
m_cpuTimingStatisticsWhenPause = currentCpuTimingStatistics;
CollectFrameData();
CullFrameData(currentCpuTimingStatistics);
CullFrameData(currentCpuTimingStatistics);
// Only listen to system ticks when the profiler is active
if (!SystemTickBus::Handler::BusIsConnected())
@@ -148,7 +148,7 @@ namespace AZ
}
}
ImGui::End();
if (m_captureToFile)
{
AZStd::sys_time_t timeNow = AZStd::GetTimeNowSecond();
@@ -325,7 +325,7 @@ namespace AZ
{
const bool ascending = sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending;
const ImS16 columnToSort = sortSpecs->Specs->ColumnIndex;
switch (columnToSort)
{
case (0): // Sort by group name
@@ -343,7 +343,7 @@ namespace AZ
case (4): // Sort by invocations
AZStd::sort(m_tableData.begin(), m_tableData.end(), TableRow::TableRowCompareFunctor(&TableRow::m_invocationsLastFrame, ascending));
break;
case (5): // Sort by total time
case (5): // Sort by total time
AZStd::sort(m_tableData.begin(), m_tableData.end(), TableRow::TableRowCompareFunctor(&TableRow::m_lastFrameTotalTicks, ascending));
break;
}
@@ -401,7 +401,7 @@ namespace AZ
}
DrawTable();
}
}
}
inline void ImGuiCpuProfiler::DrawFilePicker()
@@ -460,17 +460,17 @@ namespace AZ
const auto [groupRegionNameItr, wasGroupRegionNameInserted] =
m_deserializedGroupRegionNamePool.emplace(groupNameItr->c_str(), regionNameItr->c_str());
const RHI::CachedTimeRegion newRegion(&(*groupRegionNameItr), entry.m_stackDepth, entry.m_startTick, entry.m_endTick);
const RHI::CachedTimeRegion newRegion(*groupRegionNameItr, entry.m_stackDepth, entry.m_startTick, entry.m_endTick);
m_savedData[entry.m_threadId].push_back(newRegion);
// Since we don't serialize the frame boundaries, we need to use the RPI's OnSystemTick event as a heuristic.
// Since we don't serialize the frame boundaries, we need to use the RPI's OnSystemTick event as a heuristic.
const static Name frameBoundaryName = Name("RPISystem: OnSystemTick");
if (entry.m_regionName == frameBoundaryName)
{
m_frameEndTicks.push_back(entry.m_endTick);
}
}
// Update running statistics
// Update running statistics
if (!m_groupRegionMap[*groupNameItr].contains(*regionNameItr))
{
m_groupRegionMap[*groupNameItr][*regionNameItr].m_groupName = *groupNameItr;
@@ -487,7 +487,7 @@ namespace AZ
// Invariant: each vector in m_savedData must be sorted so that we can efficiently cull region data.
for (auto& [threadId, singleThreadData] : m_savedData)
{
AZStd::sort(singleThreadData.begin(), singleThreadData.end(),
AZStd::sort(singleThreadData.begin(), singleThreadData.end(),
[](const TimeRegion& lhs, const TimeRegion& rhs)
{
return lhs.m_startTick < rhs.m_startTick;
@@ -669,7 +669,7 @@ namespace AZ
// Iterate through the entire TimeRegionMap and copy the data since it will get deleted on the next frame
for (const auto& [threadId, singleThreadRegionMap] : timeRegionMap)
{
const size_t threadIdHashed = AZStd::hash<AZStd::thread_id>{}(threadId);
const size_t threadIdHashed = AZStd::hash<AZStd::thread_id>{}(threadId);
// The profiler can sometime return threads without any profiling events when dropping threads, FIXME(ATOM-15949)
if (singleThreadRegionMap.size() == 0)
{
@@ -686,7 +686,7 @@ namespace AZ
newVisualizerData.push_back(region); // Copies
// Also update the statistical view's data
const AZStd::string& groupName = region.m_groupRegionName->m_groupName;
const AZStd::string& groupName = region.m_groupRegionName.m_groupName;
if (!m_groupRegionMap[groupName].contains(regionName))
{
@@ -765,7 +765,7 @@ namespace AZ
inline void ImGuiCpuProfiler::DrawBlock(const TimeRegion& block, u64 targetRow)
{
// Don't draw anything if the user is searching for regions and this block doesn't pass the filter
if (!m_visualizerHighlightFilter.PassFilter(block.m_groupRegionName->m_regionName))
if (!m_visualizerHighlightFilter.PassFilter(block.m_groupRegionName.m_regionName))
{
return;
}
@@ -798,7 +798,7 @@ namespace AZ
if (regionPixelWidth > maxCharWidth) // We can draw at least one character
{
const AZStd::string label =
AZStd::string::format("%s/ %s", block.m_groupRegionName->m_groupName, block.m_groupRegionName->m_regionName);
AZStd::string::format("%s/ %s", block.m_groupRegionName.m_groupName, block.m_groupRegionName.m_regionName);
const float textWidth = ImGui::CalcTextSize(label.c_str()).x;
if (regionPixelWidth < textWidth) // Not enough space in the block to draw the whole name, draw clipped text.
@@ -809,7 +809,7 @@ namespace AZ
// so we must adjust for the scale manually.
const float scaleFactor = ImGui::GetIO().FontGlobalScale;
const float fontSize = ImGui::GetFont()->FontSize * scaleFactor;
ImGui::GetFont()->RenderText(drawList, fontSize, startPoint, IM_COL32_WHITE, clipRect, label.c_str(), 0);
}
else // We have enough space to draw the entire label, draw and center text.
@@ -828,7 +828,7 @@ namespace AZ
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
m_enableVisualizer = false;
const auto newFilter = AZStd::string(block.m_groupRegionName->m_regionName);
const auto newFilter = AZStd::string(block.m_groupRegionName.m_regionName);
m_timedRegionFilter = ImGuiTextFilter(newFilter.c_str());
m_timedRegionFilter.Build();
}
@@ -836,7 +836,7 @@ namespace AZ
drawList->AddRect(startPoint, endPoint, ImGui::GetColorU32({ 1, 1, 1, 1 }), 0.0, 0, 1.5);
ImGui::BeginTooltip();
ImGui::Text("%s::%s", block.m_groupRegionName->m_groupName, block.m_groupRegionName->m_regionName);
ImGui::Text("%s::%s", block.m_groupRegionName.m_groupName, block.m_groupRegionName.m_regionName);
ImGui::Text("Execution time: %.3f ms", CpuProfilerImGuiHelper::TicksToMs(block.m_endTick - block.m_startTick));
ImGui::Text("Ticks %lld => %lld", block.m_startTick, block.m_endTick);
ImGui::EndTooltip();
@@ -846,10 +846,10 @@ namespace AZ
inline ImU32 ImGuiCpuProfiler::GetBlockColor(const TimeRegion& block)
{
// Use the GroupRegionName pointer a key into the cache, equal regions will have equal pointers
const GroupRegionName* key = block.m_groupRegionName;
if (m_regionColorMap.contains(key)) // Cache hit
const GroupRegionName& key = block.m_groupRegionName;
if (auto iter = m_regionColorMap.find(key); iter != m_regionColorMap.end()) // Cache hit
{
return ImGui::GetColorU32(m_regionColorMap[key]);
return ImGui::GetColorU32(iter->second);
}
// Cache miss, generate a new random color
@@ -231,7 +231,7 @@ namespace SurfaceData
void SurfaceDataMeshComponent::UpdateMeshData()
{
AZ_PROFILE_FUNCTION(Entity);
AZ_PROFILE_SCOPE(Entity, "SurfaceDataMeshComponent: UpdateMeshData");
bool meshValidBeforeUpdate = false;
bool meshValidAfterUpdate = false;