diff --git a/Code/Framework/AzCore/AzCore/Debug/Timer.h b/Code/Framework/AzCore/AzCore/Debug/Timer.h index 47bd3e1b95..6585fe7468 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Timer.h +++ b/Code/Framework/AzCore/AzCore/Debug/Timer.h @@ -46,5 +46,23 @@ namespace AZ private: AZStd::sys_time_t m_timeStamp; }; + + //! Utility type that updates the given variable with the lifetime of the object in cycles. + //! Useful for quick scope based timing. + struct ScopedTimer + { + explicit ScopedTimer(AZStd::sys_time_t& variable) + : m_variable(variable) + { + m_timer.Stamp(); + } + ~ScopedTimer() + { + m_variable = m_timer.GetDeltaTimeInTicks(); + } + + AZStd::sys_time_t& m_variable; + Timer m_timer; + }; } } diff --git a/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp index a476b5b839..4accbf0bba 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -457,17 +456,8 @@ namespace AZ JsonSerializerSettings serializationSettings; serializationSettings.m_keepDefaults = true; - double frameTime = 0.0; - const AZ::RHI::CpuTimingStatistics* stats = AZ::RHI::RHISystemInterface::Get()->GetCpuTimingStatistics(); - if (stats) - { - frameTime = stats->GetFrameToFrameTimeMilliseconds(); - } - else - { - AZStd::string warning = AZStd::string::format("Failed to get Cpu frame time"); - AZ_Warning("ProfilingCaptureSystemComponent", false, warning.c_str()); - } + double frameTime = AZ::RHI::RHISystemInterface::Get()->GetCpuFrameTime(); + AZ_Warning("ProfilingCaptureSystemComponent", frameTime > 0, "Failed to get Cpu frame time"); CpuFrameTimeSerializer serializer(frameTime); const auto saveResult = JsonSerializationUtils::SaveObjectToFile(&serializer, diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Base.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Base.h index 9e1ec4585e..977c2c9ce8 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Base.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Base.h @@ -16,6 +16,7 @@ #include AZ_DECLARE_BUDGET(RHI); +inline static constexpr AZ::Crc32 rhiMetricsId = AZ_CRC_CE("RHI"); namespace UnitTest { diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/CpuTimingStatistics.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/CpuTimingStatistics.h deleted file mode 100644 index 2ab23def08..0000000000 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/CpuTimingStatistics.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - -#include - -#include -#include -#include -#include - -namespace AZ -{ - namespace RHI - { - //! Container and helper type for storing per frame CPU timing data. - //! Users can queue up generic timings in Scopes or add to specific timing data. - struct CpuTimingStatistics - { - struct QueueStatistics - { - //! The display name of the queue the statistics are for. - Name m_queueName; - - //! Time spent executing queued work. - AZStd::sys_time_t m_executeDuration{}; - }; - - //! Statistics for each command queue. - AZStd::vector m_queueStatistics; - - //! The amount of time spent between two calls to EndFrame. - AZStd::sys_time_t m_frameToFrameTime{}; - - //! The amount of time spent presenting (vsync can affect this). - AZStd::sys_time_t m_presentDuration{}; - - void Reset() - { - m_queueStatistics.clear(); - } - - double GetFrameToFrameTimeMilliseconds() const - { - return (m_frameToFrameTime * 1000) / aznumeric_cast(AZStd::GetTimeTicksPerSecond()); - } - }; - - //! Utility type that updates the given variable with the lifetime of the object in cycles. - //! Useful for quick scope based timing. - struct VariableTimer - { - VariableTimer() = delete; - VariableTimer(AZStd::sys_time_t& variable) - : m_variable(variable) - { - m_timer.Stamp(); - } - ~VariableTimer() - { - m_variable = m_timer.GetDeltaTimeInTicks(); - } - - AZStd::sys_time_t& m_variable; - AZ::Debug::Timer m_timer; - }; - } -} - -//! Utility for timing a section of code and writing the timing (in cycles) to the given variable. -#define AZ_PROFILE_RHI_VARIABLE(variable) \ - AZ::RHI::VariableTimer AZ_JOIN(variableTimer, __LINE__)(variable); diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h index fb4082bb25..358fdcb4c4 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h @@ -27,9 +27,6 @@ namespace AZ { namespace RHI { - struct CpuTimingStatistics; - - //! The Device is a context for managing GPU state and memory on a physical device. The user creates //! a device instance from a PhysicalDevice. Each device has its own capabilities and limits, and can //! be configured to buffer a specific number of frames. @@ -91,10 +88,10 @@ namespace AZ //! scope. Otherwise, an error code is returned. ResultCode CompileMemoryStatistics(MemoryStatistics& memoryStatistics, MemoryStatisticsReportFlags reportFlags); - //! Fills the provided data structure with cpu timing statistics specific to this device. This - //! method can only be called on an initialized device, and outside of the BeginFrame / EndFrame - //! scope. Otherwise, an error code is returned. - ResultCode UpdateCpuTimingStatistics(CpuTimingStatistics& cpuTimingStatistics) const; + //! Pushes internally recorded timing statistics upwards into the global stats profiler, under the RHI section. + //! This method can only be called on an initialized device, and outside of the BeginFrame / EndFrame scope. + //! Otherwise, an error code is returned. + ResultCode UpdateCpuTimingStatistics() const; //! Returns the physical device associated with this device. const PhysicalDevice& GetPhysicalDevice() const; @@ -186,7 +183,7 @@ namespace AZ virtual void CompileMemoryStatisticsInternal(MemoryStatisticsBuilder& builder) = 0; //! Called when the device is reporting cpu timing statistics. - virtual void UpdateCpuTimingStatisticsInternal(CpuTimingStatistics& cpuTimingStatistics) const = 0; + virtual void UpdateCpuTimingStatisticsInternal() const = 0; //! Fills the capabilities for each format. virtual void FillFormatsCapabilitiesInternal(FormatCapabilitiesList& formatsCapabilities) = 0; diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameScheduler.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameScheduler.h index 48e7e0f339..eb2b0b5b0c 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameScheduler.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameScheduler.h @@ -7,7 +7,6 @@ */ #pragma once -#include #include #include #include @@ -168,8 +167,8 @@ namespace AZ /// Returns the timing statistics for the previous frame. const TransientAttachmentStatistics* GetTransientAttachmentStatistics() const; - /// Returns cpu timing statistics for the previous frame. - const CpuTimingStatistics* GetCpuTimingStatistics() const; + /// Returns current CPU frame to frame time in milliseconds. + double GetCpuFrameTime() const; /// Returns memory statistics for the previous frame. const MemoryStatistics* GetMemoryStatistics() const; @@ -216,7 +215,6 @@ namespace AZ Ptr m_transientAttachmentPool; - CpuTimingStatistics m_cpuTimingStatistics; AZStd::sys_time_t m_lastFrameEndTime{}; MemoryStatistics m_memoryStatistics; diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystem.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystem.h index 599108654a..52a44c0903 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystem.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystem.h @@ -48,7 +48,7 @@ namespace AZ RHI::PipelineStateCache* GetPipelineStateCache() override; const RHI::FrameSchedulerCompileRequest& GetFrameSchedulerCompileRequest() const override; void ModifyFrameSchedulerStatisticsFlags(RHI::FrameSchedulerStatisticsFlags statisticsFlags, bool enableFlags) override; - const RHI::CpuTimingStatistics* GetCpuTimingStatistics() const override; + double GetCpuFrameTime() const override; const RHI::TransientAttachmentStatistics* GetTransientAttachmentStatistics() const override; const RHI::MemoryStatistics* GetMemoryStatistics() const override; const RHI::TransientAttachmentPoolDescriptor* GetTransientAttachmentPoolDescriptor() const override; diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystemInterface.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystemInterface.h index 6a9650e0a1..19ba1cb762 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystemInterface.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystemInterface.h @@ -27,7 +27,6 @@ namespace AZ class PipelineStateCache; class PlatformLimitsDescriptor; class RayTracingShaderTable; - struct CpuTimingStatistics; struct FrameSchedulerCompileRequest; struct TransientAttachmentStatistics; struct TransientAttachmentPoolDescriptor; @@ -55,7 +54,7 @@ namespace AZ virtual void ModifyFrameSchedulerStatisticsFlags(RHI::FrameSchedulerStatisticsFlags statisticsFlags, bool enableFlags) = 0; - virtual const RHI::CpuTimingStatistics* GetCpuTimingStatistics() const = 0; + virtual double GetCpuFrameTime() const = 0; virtual const RHI::TransientAttachmentStatistics* GetTransientAttachmentStatistics() const = 0; diff --git a/Gems/Atom/RHI/Code/Source/RHI/CommandQueue.cpp b/Gems/Atom/RHI/Code/Source/RHI/CommandQueue.cpp index f65c36f2ed..a365b23e94 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/CommandQueue.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/CommandQueue.cpp @@ -32,6 +32,23 @@ namespace AZ return ResultCode::InvalidOperation; } #endif + + if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) + { + auto& rhiMetrics = statsProfiler->GetProfiler(rhiMetricsId); + + static constexpr AZStd::string_view presentStatName("Present"); + static constexpr AZ::Crc32 presentStatId(presentStatName); + rhiMetrics.GetStatsManager().AddStatistic(presentStatId, presentStatName, /*units=*/"clocks", /*failIfExist=*/false); + + if (!GetName().IsEmpty()) + { + const AZStd::string commandQueueName(GetName().GetCStr()); + const AZ::Crc32 commandQueueId(GetName().GetHash()); + rhiMetrics.GetStatsManager().AddStatistic(commandQueueId, commandQueueName, /*units=*/"clocks", /*failIfExist=*/false); + } + } + const ResultCode resultCode = InitInternal(device, descriptor); if (resultCode == ResultCode::Success) diff --git a/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp b/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp index 1bc17adb22..826e0b6aa3 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp @@ -12,6 +12,7 @@ #include #include +#include #include namespace AZ @@ -73,6 +74,11 @@ namespace AZ m_initialized = true; SystemTickBus::Handler::BusConnect(); m_continuousCaptureData.set_capacity(10); + + if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) + { + statsProfiler->ActivateProfiler(AZ_CRC_CE("RHI"), true); + } } void CpuProfilerImpl::Shutdown() diff --git a/Gems/Atom/RHI/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Code/Source/RHI/Device.cpp index 2f4ca297a1..c8497cf7b1 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/Device.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/Device.cpp @@ -160,11 +160,11 @@ namespace AZ return ResultCode::InvalidOperation; } - ResultCode Device::UpdateCpuTimingStatistics(CpuTimingStatistics& cpuTimingStatistics) const + ResultCode Device::UpdateCpuTimingStatistics() const { if (ValidateIsNotInFrame()) { - UpdateCpuTimingStatisticsInternal(cpuTimingStatistics); + UpdateCpuTimingStatisticsInternal(); return ResultCode::Success; } return ResultCode::InvalidOperation; diff --git a/Gems/Atom/RHI/Code/Source/RHI/FrameScheduler.cpp b/Gems/Atom/RHI/Code/Source/RHI/FrameScheduler.cpp index 0d3ac8216b..a15db9e24b 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/FrameScheduler.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/FrameScheduler.cpp @@ -35,6 +35,9 @@ namespace AZ { namespace RHI { + static constexpr const char* frameTimeMetricName = "Frame to Frame Time"; + static constexpr AZ::Crc32 frameTimeMetricId = AZ_CRC_CE(frameTimeMetricName); + ResultCode FrameScheduler::Init(Device& device, const FrameSchedulerDescriptor& descriptor) { ResultCode resultCode = ResultCode::Success; @@ -81,6 +84,12 @@ namespace AZ m_taskGraphActive = AZ::Interface::Get(); + if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) + { + auto& rhiMetrics = statsProfiler->GetProfiler(rhiMetricsId); + rhiMetrics.GetStatsManager().AddStatistic(frameTimeMetricId, frameTimeMetricName, /*units=*/"clocks", /*failIfExist=*/false); + } + m_lastFrameEndTime = AZStd::GetTimeNowTicks(); return ResultCode::Success; @@ -278,7 +287,7 @@ namespace AZ AZ::TaskDescriptor srgCompileEndDesc{"SrgCompileEnd", "Graphics"}; auto srgCompileEndTask = taskGraph.AddTask( - srgCompileEndDesc, + srgCompileEndDesc, [srgPool]() { srgPool->CompileGroupsEnd(); @@ -449,7 +458,7 @@ namespace AZ m_device->CompileMemoryStatistics(m_memoryStatistics, MemoryStatisticsReportFlags::Detail); } - m_device->UpdateCpuTimingStatistics(m_cpuTimingStatistics); + m_device->UpdateCpuTimingStatistics(); m_scopeProducers.clear(); m_scopeProducerLookup.clear(); @@ -460,7 +469,10 @@ namespace AZ } const AZStd::sys_time_t timeNowTicks = AZStd::GetTimeNowTicks(); - m_cpuTimingStatistics.m_frameToFrameTime = timeNowTicks - m_lastFrameEndTime; + if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) + { + statsProfiler->PushSample(rhiMetricsId, frameTimeMetricId, static_cast(timeNowTicks - m_lastFrameEndTime)); + } m_lastFrameEndTime = timeNowTicks; return ResultCode::Success; @@ -588,12 +600,18 @@ namespace AZ : nullptr; } - const CpuTimingStatistics* FrameScheduler::GetCpuTimingStatistics() const + double FrameScheduler::GetCpuFrameTime() const { - return - CheckBitsAny(m_compileRequest.m_statisticsFlags, FrameSchedulerStatisticsFlags::GatherCpuTimingStatistics) - ? &m_cpuTimingStatistics - : nullptr; + if (CheckBitsAny(m_compileRequest.m_statisticsFlags, FrameSchedulerStatisticsFlags::GatherCpuTimingStatistics)) + { + if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) + { + auto& rhiMetrics = statsProfiler->GetProfiler(rhiMetricsId); + const auto* frameTimeStat = rhiMetrics.GetStatistic(frameTimeMetricId); + return (frameTimeStat->GetMostRecentSample() * 1000) / aznumeric_cast(AZStd::GetTimeTicksPerSecond()); + } + } + return 0; } ScopeId FrameScheduler::GetRootScopeId() const diff --git a/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp b/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp index 744b688c60..b40ad3e11a 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp @@ -254,9 +254,9 @@ namespace AZ : RHI::ResetBits(m_compileRequest.m_statisticsFlags, statisticsFlags); } - const RHI::CpuTimingStatistics* RHISystem::GetCpuTimingStatistics() const + double RHISystem::GetCpuFrameTime() const { - return m_frameScheduler.GetCpuTimingStatistics(); + return m_frameScheduler.GetCpuFrameTime(); } const RHI::TransientAttachmentStatistics* RHISystem::GetTransientAttachmentStatistics() const diff --git a/Gems/Atom/RHI/Code/Tests/Device.h b/Gems/Atom/RHI/Code/Tests/Device.h index d3177fc823..2b6a81face 100644 --- a/Gems/Atom/RHI/Code/Tests/Device.h +++ b/Gems/Atom/RHI/Code/Tests/Device.h @@ -47,7 +47,7 @@ namespace UnitTest void CompileMemoryStatisticsInternal(AZ::RHI::MemoryStatisticsBuilder&) override {} - void UpdateCpuTimingStatisticsInternal([[maybe_unused]] AZ::RHI::CpuTimingStatistics& cpuTimingStatistics) const override {} + void UpdateCpuTimingStatisticsInternal() const override {} AZStd::chrono::microseconds GpuTimestampToMicroseconds([[maybe_unused]] uint64_t gpuTimestamp, [[maybe_unused]] AZ::RHI::HardwareQueueClass queueClass) const override { diff --git a/Gems/Atom/RHI/Code/atom_rhi_reflect_files.cmake b/Gems/Atom/RHI/Code/atom_rhi_reflect_files.cmake index e211462eeb..9a2b6e8765 100644 --- a/Gems/Atom/RHI/Code/atom_rhi_reflect_files.cmake +++ b/Gems/Atom/RHI/Code/atom_rhi_reflect_files.cmake @@ -112,7 +112,6 @@ set(FILES Source/RHI.Reflect/ShaderResourceGroupLayout.cpp Source/RHI.Reflect/ShaderResourceGroupLayoutDescriptor.cpp Source/RHI.Reflect/ShaderResourceGroupPoolDescriptor.cpp - Include/Atom/RHI.Reflect/CpuTimingStatistics.h Include/Atom/RHI.Reflect/MemoryStatistics.h Include/Atom/RHI.Reflect/TransientAttachmentStatistics.h Include/Atom/RHI.Reflect/SwapChainDescriptor.h diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueue.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueue.cpp index 0cde6aeb09..7ab2b07b03 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueue.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueue.cpp @@ -10,8 +10,8 @@ #include #include #include -#include -#include + +#include namespace AZ { @@ -139,7 +139,7 @@ namespace AZ QueueCommand([=](void* commandQueue) { AZ_PROFILE_SCOPE(RHI, "ExecuteWork"); - AZ_PROFILE_RHI_VARIABLE(m_lastExecuteDuration); + AZ::Debug::ScopedTimer executionTimer(m_lastExecuteDuration); static const uint32_t CommandListCountMax = 128; ID3D12CommandQueue* dx12CommandQueue = static_cast(commandQueue); @@ -185,7 +185,7 @@ namespace AZ dx12CommandQueue->Signal(fence->Get(), fence->GetPendingValue()); } - AZ_PROFILE_RHI_VARIABLE(m_lastPresentDuration); + AZ::Debug::ScopedTimer presentTimer(m_lastPresentDuration); for (RHI::SwapChain* swapChain : request.m_swapChainsToPresent) { swapChain->Present(); diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp index 012784d3fc..5692809443 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp @@ -7,7 +7,6 @@ */ #include -#include #include #include #include @@ -183,17 +182,22 @@ namespace AZ return *m_commandQueues[static_cast(hardwareQueueClass)]; } - void CommandQueueContext::UpdateCpuTimingStatistics(RHI::CpuTimingStatistics& cpuTimingStatistics) const + void CommandQueueContext::UpdateCpuTimingStatistics() const { - cpuTimingStatistics.Reset(); - - AZStd::sys_time_t presentDuration = 0; - for (const RHI::Ptr& commandQueue : m_commandQueues) + if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) { - cpuTimingStatistics.m_queueStatistics.push_back({ commandQueue->GetName(), commandQueue->GetLastExecuteDuration() }); - presentDuration += commandQueue->GetLastPresentDuration(); + auto& rhiMetrics = statsProfiler->GetProfiler(rhiMetricsId); + + AZStd::sys_time_t presentDuration = 0; + for (const RHI::Ptr& commandQueue : m_commandQueues) + { + const AZ::Crc32 commandQueueId(commandQueue->GetName().GetHash()); + rhiMetrics.PushSample(commandQueueId, static_cast(commandQueue->GetLastExecuteDuration())); + presentDuration += commandQueue->GetLastPresentDuration(); + } + + rhiMetrics.PushSample(AZ_CRC_CE("Present"), static_cast(presentDuration)); } - cpuTimingStatistics.m_presentDuration = presentDuration; } const FenceSet& CommandQueueContext::GetCompiledFences() diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.h b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.h index cf820026aa..dff1741109 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.h +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.h @@ -14,11 +14,6 @@ namespace AZ { - namespace RHI - { - struct CpuTimingStatistics; - } - namespace DX12 { class CommandQueueContext @@ -49,7 +44,7 @@ namespace AZ RHI::HardwareQueueClass hardwareQueueClass, const ExecuteWorkRequest& request); - void UpdateCpuTimingStatistics(RHI::CpuTimingStatistics& cpuTimingStatistics) const; + void UpdateCpuTimingStatistics() const; // Fences across all queues that are compiled by the frame graph compilation phase const FenceSet& GetCompiledFences(); diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp index 6f614499d2..3d44e56953 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp @@ -184,9 +184,9 @@ namespace AZ m_stagingMemoryAllocator.ReportMemoryUsage(builder); } - void Device::UpdateCpuTimingStatisticsInternal(RHI::CpuTimingStatistics& cpuTimingStatistics) const + void Device::UpdateCpuTimingStatisticsInternal() const { - m_commandQueueContext.UpdateCpuTimingStatistics(cpuTimingStatistics); + m_commandQueueContext.UpdateCpuTimingStatistics(); } void Device::EndFrameInternal() diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.h b/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.h index 40e26db891..29e006fca0 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.h +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.h @@ -147,7 +147,7 @@ namespace AZ void ShutdownInternal() override; void CompileMemoryStatisticsInternal(RHI::MemoryStatisticsBuilder& builder) override; - void UpdateCpuTimingStatisticsInternal(RHI::CpuTimingStatistics& cpuTimingStatistics) const override; + void UpdateCpuTimingStatisticsInternal() const override; void BeginFrameInternal() override; void EndFrameInternal() override; void WaitForIdleInternal() override; diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueue.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueue.cpp index d151a11ec1..a1f4616147 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueue.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueue.cpp @@ -5,14 +5,15 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ -#include -#include + #include #include #include #include #include +#include + namespace AZ { namespace Metal @@ -115,7 +116,7 @@ namespace AZ @autoreleasepool { AZ_PROFILE_SCOPE(RHI, "ExecuteWork"); - AZ_PROFILE_RHI_VARIABLE(m_lastExecuteDuration); + AZ::Debug::ScopedTimer executionTimer(m_lastExecuteDuration); if (request.m_signalFenceValue > 0) { @@ -128,7 +129,7 @@ namespace AZ } { - AZ_PROFILE_RHI_VARIABLE(m_lastPresentDuration); + AZ::Debug::ScopedTimer presentTimer(m_lastPresentDuration); for (RHI::SwapChain* swapChain : request.m_swapChainsToPresent) { diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueueContext.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueueContext.cpp index e4c651c2b1..37f8a8bab8 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueueContext.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueueContext.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -135,18 +134,23 @@ namespace AZ m_commandQueues[hardwareQueueIdx]->QueueGpuSignal(fence); } } - - void CommandQueueContext::UpdateCpuTimingStatistics(RHI::CpuTimingStatistics& cpuTimingStatistics) const - { - cpuTimingStatistics.Reset(); - AZStd::sys_time_t presentDuration = 0; - for (const RHI::Ptr& commandQueue : m_commandQueues) + void CommandQueueContext::UpdateCpuTimingStatistics() const + { + if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) { - cpuTimingStatistics.m_queueStatistics.push_back({ commandQueue->GetName(), commandQueue->GetLastExecuteDuration() }); - presentDuration += commandQueue->GetLastPresentDuration(); + auto& rhiMetrics = statsProfiler->GetProfiler(rhiMetricsId); + + AZStd::sys_time_t presentDuration = 0; + for (const RHI::Ptr& commandQueue : m_commandQueues) + { + const AZ::Crc32 commandQueueId(commandQueue->GetName().GetHash()); + rhiMetrics.PushSample(commandQueueId, static_cast(commandQueue->GetLastExecuteDuration())); + presentDuration += commandQueue->GetLastPresentDuration(); + } + + rhiMetrics.PushSample(AZ_CRC_CE("Present"), static_cast(presentDuration)); } - cpuTimingStatistics.m_presentDuration = presentDuration; } } } diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueueContext.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueueContext.h index 747667e1a3..41c0f63189 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueueContext.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandQueueContext.h @@ -40,7 +40,7 @@ namespace AZ /// Fences across all queues that are compiled by the frame graph compilation phase const FenceSet& GetCompiledFences(); - void UpdateCpuTimingStatistics(RHI::CpuTimingStatistics& cpuTimingStatistics) const; + void UpdateCpuTimingStatistics() const; private: AZStd::array, RHI::HardwareQueueClassCount> m_commandQueues; FenceSet m_compiledFences; diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp index 782ea7174b..76af1ecab1 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp @@ -245,9 +245,9 @@ namespace AZ { } - void Device::UpdateCpuTimingStatisticsInternal(RHI::CpuTimingStatistics& cpuTimingStatistics) const + void Device::UpdateCpuTimingStatisticsInternal() const { - m_commandQueueContext.UpdateCpuTimingStatistics(cpuTimingStatistics); + m_commandQueueContext.UpdateCpuTimingStatistics(); } void Device::FillFormatsCapabilitiesInternal(FormatCapabilitiesList& formatsCapabilities) diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h index 90dd4ff4a0..8a8ef662f9 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h @@ -161,7 +161,7 @@ namespace AZ RHI::ResultCode InitInternal(RHI::PhysicalDevice& physicalDevice) override; void ShutdownInternal() override; void CompileMemoryStatisticsInternal(RHI::MemoryStatisticsBuilder& builder) override; - void UpdateCpuTimingStatisticsInternal(RHI::CpuTimingStatistics& cpuTimingStatistics) const override; + void UpdateCpuTimingStatisticsInternal() const override; void BeginFrameInternal() override; void EndFrameInternal() override; void WaitForIdleInternal() override; diff --git a/Gems/Atom/RHI/Null/Code/Source/RHI/Device.h b/Gems/Atom/RHI/Null/Code/Source/RHI/Device.h index 27873887d4..73e1cd9119 100644 --- a/Gems/Atom/RHI/Null/Code/Source/RHI/Device.h +++ b/Gems/Atom/RHI/Null/Code/Source/RHI/Device.h @@ -32,7 +32,7 @@ namespace AZ RHI::ResultCode InitInternal([[maybe_unused]] RHI::PhysicalDevice& physicalDevice) override { return RHI::ResultCode::Success; } void ShutdownInternal() override {} void CompileMemoryStatisticsInternal([[maybe_unused]] RHI::MemoryStatisticsBuilder& builder) override {} - void UpdateCpuTimingStatisticsInternal([[maybe_unused]] RHI::CpuTimingStatistics& cpuTimingStatistics) const override {} + void UpdateCpuTimingStatisticsInternal() const override {} void BeginFrameInternal() override {} void EndFrameInternal() override {} void WaitForIdleInternal() override {} diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp index c712099172..6a43b66474 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp @@ -5,13 +5,14 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ -#include + #include #include #include #include #include -#include + +#include namespace AZ { @@ -46,7 +47,7 @@ namespace AZ QueueCommand([=](void* queue) { AZ_PROFILE_SCOPE(RHI, "ExecuteWork"); - AZ_PROFILE_RHI_VARIABLE(m_lastExecuteDuration); + AZ::Debug::ScopedTimer executionTimer(m_lastExecuteDuration); Queue* vulkanQueue = static_cast(queue); @@ -80,7 +81,7 @@ namespace AZ } { - AZ_PROFILE_RHI_VARIABLE(m_lastPresentDuration); + AZ::Debug::ScopedTimer presentTimer(m_lastPresentDuration); // present the image of the current frame. for (RHI::SwapChain* swapChain : request.m_swapChainsToPresent) diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueueContext.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueueContext.cpp index ec7311cd6e..9cf6dce77b 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueueContext.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueueContext.cpp @@ -13,7 +13,6 @@ #include #include #include -#include namespace AZ { @@ -363,17 +362,22 @@ namespace AZ return queueSelection.m_familyIndex != InvalidFamilyIndex; } - void CommandQueueContext::UpdateCpuTimingStatistics(RHI::CpuTimingStatistics& cpuTimingStatistics) const + void CommandQueueContext::UpdateCpuTimingStatistics() const { - cpuTimingStatistics.Reset(); - - AZStd::sys_time_t presentDuration = 0; - for (const RHI::Ptr& commandQueue : m_commandQueues) + if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) { - cpuTimingStatistics.m_queueStatistics.push_back({ commandQueue->GetName(), commandQueue->GetLastExecuteDuration() }); - presentDuration += commandQueue->GetLastPresentDuration(); + auto& rhiMetrics = statsProfiler->GetProfiler(rhiMetricsId); + + AZStd::sys_time_t presentDuration = 0; + for (const RHI::Ptr& commandQueue : m_commandQueues) + { + const AZ::Crc32 commandQueueId(commandQueue->GetName().GetHash()); + rhiMetrics.PushSample(commandQueueId, static_cast(commandQueue->GetLastExecuteDuration())); + presentDuration += commandQueue->GetLastPresentDuration(); + } + + rhiMetrics.PushSample(AZ_CRC_CE("Present"), static_cast(presentDuration)); } - cpuTimingStatistics.m_presentDuration = presentDuration; } } } diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueueContext.h b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueueContext.h index 8528185686..61e9b46d9f 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueueContext.h +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueueContext.h @@ -16,11 +16,6 @@ namespace AZ { - namespace RHI - { - struct CpuTimingStatistics; - } - namespace Vulkan { class Device; @@ -62,7 +57,7 @@ namespace AZ AZStd::vector GetQueueFamilyIndices(const RHI::HardwareQueueClassMask hardwareQueueClassMask) const; VkPipelineStageFlags GetSupportedPipelineStages(uint32_t queueFamilyIndex) const; - void UpdateCpuTimingStatistics(RHI::CpuTimingStatistics& cpuTimingStatistics) const; + void UpdateCpuTimingStatistics() const; private: Descriptor m_descriptor; diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp index 35bc966d1d..132f9929c1 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp @@ -547,9 +547,9 @@ namespace AZ physicalDevice.CompileMemoryStatistics(builder); } - void Device::UpdateCpuTimingStatisticsInternal(RHI::CpuTimingStatistics& cpuTimingStatistics) const + void Device::UpdateCpuTimingStatisticsInternal() const { - m_commandQueueContext.UpdateCpuTimingStatistics(cpuTimingStatistics); + m_commandQueueContext.UpdateCpuTimingStatistics(); } AZStd::vector Device::GetValidSwapChainImageFormats(const RHI::WindowHandle& windowHandle) const diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h index 13ccf9367b..9c21103929 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h @@ -126,7 +126,7 @@ namespace AZ void EndFrameInternal() override; void WaitForIdleInternal() override; void CompileMemoryStatisticsInternal(RHI::MemoryStatisticsBuilder& builder) override; - void UpdateCpuTimingStatisticsInternal(RHI::CpuTimingStatistics& cpuTimingStatistics) const override; + void UpdateCpuTimingStatisticsInternal() const override; AZStd::vector GetValidSwapChainImageFormats(const RHI::WindowHandle& windowHandle) const override; AZStd::chrono::microseconds GpuTimestampToMicroseconds(uint64_t gpuTimestamp, RHI::HardwareQueueClass queueClass) const override; void FillFormatsCapabilitiesInternal(FormatCapabilitiesList& formatsCapabilities) override; diff --git a/Gems/Atom/RPI/Code/Tests/Common/RHI/Stubs.h b/Gems/Atom/RPI/Code/Tests/Common/RHI/Stubs.h index 2ed2875cad..b8d1cfa050 100644 --- a/Gems/Atom/RPI/Code/Tests/Common/RHI/Stubs.h +++ b/Gems/Atom/RPI/Code/Tests/Common/RHI/Stubs.h @@ -61,7 +61,7 @@ namespace UnitTest void EndFrameInternal() override {} void WaitForIdleInternal() override {} void CompileMemoryStatisticsInternal(AZ::RHI::MemoryStatisticsBuilder&) override {} - void UpdateCpuTimingStatisticsInternal([[maybe_unused]] AZ::RHI::CpuTimingStatistics& cpuTimingStatistics) const override {} + void UpdateCpuTimingStatisticsInternal() const override {} AZStd::chrono::microseconds GpuTimestampToMicroseconds([[maybe_unused]] uint64_t gpuTimestamp, [[maybe_unused]] AZ::RHI::HardwareQueueClass queueClass) const override { return AZStd::chrono::microseconds(); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.cpp index 5598d894ff..c3bb13d1d2 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -96,10 +95,10 @@ namespace MaterialEditor ResetStats(); } - const AZ::RHI::CpuTimingStatistics* stats = AZ::RHI::RHISystemInterface::Get()->GetCpuTimingStatistics(); - if (stats) + double frameTime = AZ::RHI::RHISystemInterface::Get()->GetCpuFrameTime(); + if (frameTime > 0) { - m_cpuFrameTimeMs.PushSample(stats->GetFrameToFrameTimeMilliseconds()); + m_cpuFrameTimeMs.PushSample(frameTime); } AZ::RHI::Ptr rootPass = AZ::RPI::PassSystemInterface::Get()->GetRootPass(); diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h index a649fcf0f7..4a326660dd 100644 --- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h +++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h @@ -12,17 +12,11 @@ #include #include -#include #include namespace AZ { - namespace RHI - { - struct CpuTimingStatistics; - } - namespace Render { //! Stores all the data associated with a row in the table. @@ -88,11 +82,17 @@ namespace AZ using GroupRegionName = AZ::RHI::CachedTimeRegion::GroupRegionName; public: + struct CpuTimingEntry + { + const AZStd::string& m_name; + double m_executeDuration; + }; + ImGuiCpuProfiler() = default; ~ImGuiCpuProfiler() = default; //! Draws the overall CPU profiling window, defaults to the statistical view - void Draw(bool& keepDrawing, const AZ::RHI::CpuTimingStatistics& cpuTimingStatistics); + void Draw(bool& keepDrawing); private: static constexpr float RowHeight = 35.0; @@ -121,11 +121,14 @@ namespace AZ // Sort the table by a given column, rearranges the pointers in m_tableData. void SortTable(ImGuiTableSortSpecs* sortSpecs); + // gather the latest timing statistics + void CacheCpuTimingStatistics(); + // Get the profiling data from the last frame, only called when the profiler is not paused. void CollectFrameData(); // Cull old data from internal storage, only called when profiler is not paused. - void CullFrameData(const AZ::RHI::CpuTimingStatistics& currentCpuTimingStatistics); + void CullFrameData(); // Draws a single block onto the timeline into the specified row void DrawBlock(const TimeRegion& block, u64 targetRow); @@ -204,7 +207,8 @@ namespace AZ bool m_enableVisualizer = false; // Last captured CPU timing statistics - AZ::RHI::CpuTimingStatistics m_cpuTimingStatisticsWhenPause; + AZStd::vector m_cpuTimingStatisticsWhenPause; + AZStd::sys_time_t m_frameToFrameTime{}; AZStd::string m_lastCapturedFilePath; diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl index a573e3019a..daf6eca5c0 100644 --- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl +++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl @@ -7,7 +7,6 @@ */ #include -#include #include #include #include @@ -16,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +31,7 @@ namespace AZ { namespace CpuProfilerImGuiHelper { - inline float TicksToMs(AZStd::sys_time_t ticks) + inline float TicksToMs(double ticks) { // Note: converting to microseconds integer before converting to milliseconds float const AZStd::sys_time_t ticksPerSecond = AZStd::GetTimeTicksPerSecond(); @@ -39,6 +39,11 @@ namespace AZ return static_cast((ticks * 1000) / (ticksPerSecond / 1000)) / 1000.0f; } + inline float TicksToMs(AZStd::sys_time_t ticks) + { + return TicksToMs(static_cast(ticks)); + } + using DeserializedCpuData = AZStd::vector; inline Outcome LoadSavedCpuProfilingStatistics(const AZStd::string& capturePath) { @@ -108,7 +113,9 @@ namespace AZ } } // namespace CpuProfilerImGuiHelper - inline void ImGuiCpuProfiler::Draw(bool& keepDrawing, const AZ::RHI::CpuTimingStatistics& currentCpuTimingStatistics) + + + inline void ImGuiCpuProfiler::Draw(bool& keepDrawing) { // Cache the value to detect if it was changed by ImGui(user pressed 'x') const bool cachedShowCpuProfiler = keepDrawing; @@ -121,10 +128,10 @@ namespace AZ if (!m_paused) { // Update region map and cache the input cpu timing statistics when the profiling is not paused - m_cpuTimingStatisticsWhenPause = currentCpuTimingStatistics; + CacheCpuTimingStatistics(); CollectFrameData(); - CullFrameData(currentCpuTimingStatistics); + CullFrameData(); // Only listen to system ticks when the profiler is active if (!SystemTickBus::Handler::BusIsConnected()) @@ -354,19 +361,12 @@ namespace AZ { DrawCommonHeader(); - const AZ::RHI::CpuTimingStatistics& cpuTimingStatistics = m_cpuTimingStatisticsWhenPause; - - const auto ShowTimeInMs = [](AZStd::sys_time_t duration) - { - ImGui::Text("%.2f ms", CpuProfilerImGuiHelper::TicksToMs(duration)); - }; - - const auto ShowRow = [&ShowTimeInMs](const char* regionLabel, AZStd::sys_time_t duration) + const auto ShowRow = [](const char* regionLabel, double duration) { ImGui::Text("%s", regionLabel); ImGui::NextColumn(); - ShowTimeInMs(duration); + ImGui::Text("%.2f ms", CpuProfilerImGuiHelper::TicksToMs(duration)); ImGui::NextColumn(); }; @@ -377,11 +377,9 @@ namespace AZ ImGui::SetColumnWidth(0, 660.0f); ImGui::SetColumnWidth(1, 100.0f); - ShowRow("Frame to Frame Time", cpuTimingStatistics.m_frameToFrameTime); - ShowRow("Present Time", cpuTimingStatistics.m_presentDuration); - for (const auto& queueStatistics : cpuTimingStatistics.m_queueStatistics) + for (const auto& queueStatistics : m_cpuTimingStatisticsWhenPause) { - ShowRow(queueStatistics.m_queueName.GetCStr(), queueStatistics.m_executeDuration); + ShowRow(queueStatistics.m_name.c_str(), queueStatistics.m_executeDuration); } ImGui::Separator(); @@ -653,6 +651,32 @@ namespace AZ ImGui::EndChild(); } + inline void ImGuiCpuProfiler::CacheCpuTimingStatistics() + { + using namespace AZ::Statistics; + + m_cpuTimingStatisticsWhenPause.clear(); + if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) + { + auto& rhiMetrics = statsProfiler->GetProfiler(AZ_CRC_CE("RHI")); + + const NamedRunningStatistic* frameTimeMetric = rhiMetrics.GetStatistic(AZ_CRC_CE("Frame to Frame Time")); + if (frameTimeMetric) + { + m_frameToFrameTime = static_cast(frameTimeMetric->GetMostRecentSample()); + } + + AZStd::vector statistics; + rhiMetrics.GetStatsManager().GetAllStatistics(statistics); + + for (NamedRunningStatistic* stat : statistics) + { + m_cpuTimingStatisticsWhenPause.push_back({ stat->GetName(), stat->GetMostRecentSample() }); + stat->Reset(); + } + } + } + inline void ImGuiCpuProfiler::CollectFrameData() { // We maintain separate datastores for the visualizer and the statistical view because they require different @@ -721,10 +745,9 @@ namespace AZ } } - inline void ImGuiCpuProfiler::CullFrameData(const AZ::RHI::CpuTimingStatistics& currentCpuTimingStatistics) + inline void ImGuiCpuProfiler::CullFrameData() { - const AZStd::sys_time_t frameToFrameTime = currentCpuTimingStatistics.m_frameToFrameTime; - const AZStd::sys_time_t deleteBeforeTick = AZStd::GetTimeNowTicks() - frameToFrameTime * m_framesToCollect; + const AZStd::sys_time_t deleteBeforeTick = AZStd::GetTimeNowTicks() - m_frameToFrameTime * m_framesToCollect; // Remove old frame boundary data auto firstBoundaryToKeepItr = AZStd::upper_bound(m_frameEndTicks.begin(), m_frameEndTicks.end(), deleteBeforeTick); diff --git a/Gems/AtomLyIntegration/AtomImGuiTools/Code/Source/AtomImGuiToolsSystemComponent.cpp b/Gems/AtomLyIntegration/AtomImGuiTools/Code/Source/AtomImGuiToolsSystemComponent.cpp index ec18997a01..b369ab2ee2 100644 --- a/Gems/AtomLyIntegration/AtomImGuiTools/Code/Source/AtomImGuiToolsSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomImGuiTools/Code/Source/AtomImGuiToolsSystemComponent.cpp @@ -86,11 +86,7 @@ namespace AtomImGuiTools } if (m_showCpuProfiler) { - const AZ::RHI::CpuTimingStatistics* stats = AZ::RHI::RHISystemInterface::Get()->GetCpuTimingStatistics(); - if (stats) - { - m_imguiCpuProfiler.Draw(m_showCpuProfiler, *stats); - } + m_imguiCpuProfiler.Draw(m_showCpuProfiler); } if (m_showTransientAttachmentProfiler) {