[atom_cpu_profiler_gem_promotion] included moved files in compilation and fixed compiler errors
Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com>
This commit is contained in:
@@ -21,6 +21,7 @@ ly_add_target(
|
||||
PUBLIC
|
||||
AZ::AzCore
|
||||
AZ::AzFramework
|
||||
Gem::ImGui.Static
|
||||
)
|
||||
|
||||
# Here add Profiler target, it depends on the Profiler.Static
|
||||
@@ -37,6 +38,8 @@ ly_add_target(
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
Gem::Profiler.Static
|
||||
RUNTIME_DEPENDENCIES
|
||||
Gem::ImGui
|
||||
)
|
||||
|
||||
# By default, we will specify that the above target Profiler would be used by
|
||||
|
||||
@@ -6,14 +6,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/RHI/CpuProfilerImpl.h>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <CpuProfilerImpl.h>
|
||||
|
||||
#include <AzCore/Debug/Timer.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Statistics/StatisticalProfilerProxy.h>
|
||||
#include <Atom/RHI/RHIUtils.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
|
||||
namespace Profiler
|
||||
{
|
||||
@@ -23,7 +22,7 @@ namespace Profiler
|
||||
|
||||
CpuProfiler* CpuProfiler::Get()
|
||||
{
|
||||
return Interface<CpuProfiler>::Get();
|
||||
return AZ::Interface<CpuProfiler>::Get();
|
||||
}
|
||||
|
||||
// --- CachedTimeRegion ---
|
||||
@@ -67,10 +66,10 @@ namespace Profiler
|
||||
|
||||
void CpuProfilerImpl::Init()
|
||||
{
|
||||
Interface<AZ::Debug::Profiler>::Register(this);
|
||||
Interface<CpuProfiler>::Register(this);
|
||||
AZ::Interface<AZ::Debug::Profiler>::Register(this);
|
||||
AZ::Interface<CpuProfiler>::Register(this);
|
||||
m_initialized = true;
|
||||
SystemTickBus::Handler::BusConnect();
|
||||
AZ::SystemTickBus::Handler::BusConnect();
|
||||
m_continuousCaptureData.set_capacity(10);
|
||||
|
||||
if (auto statsProfiler = AZ::Interface<AZ::Statistics::StatisticalProfilerProxy>::Get(); statsProfiler)
|
||||
@@ -86,8 +85,8 @@ namespace Profiler
|
||||
return;
|
||||
}
|
||||
// When this call is made, no more thread profiling calls can be performed anymore
|
||||
Interface<CpuProfiler>::Unregister(this);
|
||||
Interface<AZ::Debug::Profiler>::Unregister(this);
|
||||
AZ::Interface<CpuProfiler>::Unregister(this);
|
||||
AZ::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);
|
||||
@@ -100,7 +99,7 @@ namespace Profiler
|
||||
m_initialized = false;
|
||||
m_continuousCaptureInProgress.store(false);
|
||||
m_continuousCaptureData.clear();
|
||||
SystemTickBus::Handler::BusDisconnect();
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void CpuProfilerImpl::BeginRegion(const AZ::Debug::Budget* budget, const char* eventName)
|
||||
@@ -247,7 +246,7 @@ namespace Profiler
|
||||
}
|
||||
|
||||
// Clear all TLS that flagged themselves to be deleted, meaning that the thread is already terminated
|
||||
AZStd::remove_if(m_registeredThreads.begin(), m_registeredThreads.end(), [](const RHI::Ptr<CpuTimingLocalStorage>& thread)
|
||||
AZStd::remove_if(m_registeredThreads.begin(), m_registeredThreads.end(), [](const AZStd::intrusive_ptr<CpuTimingLocalStorage>& thread)
|
||||
{
|
||||
return thread->m_deleteFlag.load();
|
||||
});
|
||||
@@ -383,7 +382,7 @@ namespace Profiler
|
||||
|
||||
// --- CpuProfilingStatisticsSerializer ---
|
||||
|
||||
CpuProfilingStatisticsSerializer::CpuProfilingStatisticsSerializer(const AZStd::ring_buffer<RHI::CpuProfiler::TimeRegionMap>& continuousData)
|
||||
CpuProfilingStatisticsSerializer::CpuProfilingStatisticsSerializer(const AZStd::ring_buffer<CpuProfiler::TimeRegionMap>& continuousData)
|
||||
{
|
||||
// Create serializable entries
|
||||
for (const auto& timeRegionMap : continuousData)
|
||||
@@ -407,8 +406,7 @@ namespace Profiler
|
||||
{
|
||||
serializeContext->Class<CpuProfilingStatisticsSerializer>()
|
||||
->Version(1)
|
||||
->Field("cpuProfilingStatisticsSerializerEntries", &CpuProfilingStatisticsSerializer::m_cpuProfilingStatisticsSerializerEntries)
|
||||
;
|
||||
->Field("cpuProfilingStatisticsSerializerEntries", &CpuProfilingStatisticsSerializer::m_cpuProfilingStatisticsSerializerEntries);
|
||||
}
|
||||
|
||||
CpuProfilingStatisticsSerializerEntry::Reflect(context);
|
||||
@@ -417,7 +415,7 @@ namespace Profiler
|
||||
// --- CpuProfilingStatisticsSerializerEntry ---
|
||||
|
||||
CpuProfilingStatisticsSerializer::CpuProfilingStatisticsSerializerEntry::CpuProfilingStatisticsSerializerEntry(
|
||||
const RHI::CachedTimeRegion& cachedTimeRegion, AZStd::thread_id threadId)
|
||||
const CachedTimeRegion& cachedTimeRegion, AZStd::thread_id threadId)
|
||||
{
|
||||
m_groupName = cachedTimeRegion.m_groupRegionName.m_groupName;
|
||||
m_regionName = cachedTimeRegion.m_groupRegionName.m_regionName;
|
||||
@@ -438,8 +436,7 @@ namespace Profiler
|
||||
->Field("stackDepth", &CpuProfilingStatisticsSerializerEntry::m_stackDepth)
|
||||
->Field("startTick", &CpuProfilingStatisticsSerializerEntry::m_startTick)
|
||||
->Field("endTick", &CpuProfilingStatisticsSerializerEntry::m_endTick)
|
||||
->Field("threadId", &CpuProfilingStatisticsSerializerEntry::m_threadId)
|
||||
;
|
||||
->Field("threadId", &CpuProfilingStatisticsSerializerEntry::m_threadId);
|
||||
}
|
||||
}
|
||||
} // namespace Profiler
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RHI/CpuProfiler.h>
|
||||
#include <Atom/RHI.Reflect/Base.h>
|
||||
#include <CpuProfiler.h>
|
||||
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
@@ -19,14 +18,13 @@
|
||||
#include <AzCore/std/parallel/shared_mutex.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_refcount.h>
|
||||
|
||||
|
||||
namespace Profiler
|
||||
{
|
||||
//! Thread local class to keep track of the thread's cached time regions.
|
||||
//! Each thread keeps track of its own time regions, which is communicated from the CpuProfilerImpl.
|
||||
//! The CpuProfilerImpl is able to request the cached time regions from the CpuTimingLocalStorage.
|
||||
class CpuTimingLocalStorage :
|
||||
public AZStd::intrusive_refcount<AZStd::atomic_uint>
|
||||
class CpuTimingLocalStorage
|
||||
: public AZStd::intrusive_refcount<AZStd::atomic_uint>
|
||||
{
|
||||
friend class CpuProfilerImpl;
|
||||
|
||||
@@ -85,7 +83,7 @@ namespace Profiler
|
||||
class CpuProfilerImpl final
|
||||
: public AZ::Debug::Profiler
|
||||
, public CpuProfiler
|
||||
, public SystemTickBus::Handler
|
||||
, public AZ::SystemTickBus::Handler
|
||||
{
|
||||
friend class CpuTimingLocalStorage;
|
||||
|
||||
@@ -101,7 +99,7 @@ namespace Profiler
|
||||
//! Unregisters the CpuProfilerImpl instance from the interface
|
||||
void Shutdown();
|
||||
|
||||
// SystemTickBus::Handler overrides
|
||||
// AZ::SystemTickBus::Handler overrides
|
||||
// When fired, the profiler collects all profiling data from registered threads and updates
|
||||
// m_timeRegionMap so that the next frame has up-to-date profiling data.
|
||||
void OnSystemTick() final override;
|
||||
@@ -130,7 +128,7 @@ namespace Profiler
|
||||
TimeRegionMap m_timeRegionMap;
|
||||
|
||||
// Set of registered threads when created
|
||||
AZStd::vector<RHI::Ptr<CpuTimingLocalStorage>, AZ::OSStdAllocator> m_registeredThreads;
|
||||
AZStd::vector<AZStd::intrusive_ptr<CpuTimingLocalStorage>, AZ::OSStdAllocator> m_registeredThreads;
|
||||
AZStd::mutex m_threadRegisterMutex;
|
||||
|
||||
// Thread local storage, gets lazily allocated when a thread is created
|
||||
@@ -164,10 +162,10 @@ namespace Profiler
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
CpuProfilingStatisticsSerializerEntry() = default;
|
||||
CpuProfilingStatisticsSerializerEntry(const RHI::CachedTimeRegion& cachedTimeRegion, AZStd::thread_id threadId);
|
||||
CpuProfilingStatisticsSerializerEntry(const CachedTimeRegion& cachedTimeRegion, AZStd::thread_id threadId);
|
||||
|
||||
Name m_groupName;
|
||||
Name m_regionName;
|
||||
AZ::Name m_groupName;
|
||||
AZ::Name m_regionName;
|
||||
uint16_t m_stackDepth;
|
||||
AZStd::sys_time_t m_startTick;
|
||||
AZStd::sys_time_t m_endTick;
|
||||
@@ -178,7 +176,7 @@ namespace Profiler
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
CpuProfilingStatisticsSerializer() = default;
|
||||
CpuProfilingStatisticsSerializer(const AZStd::ring_buffer<RHI::CpuProfiler::TimeRegionMap>& continuousData);
|
||||
CpuProfilingStatisticsSerializer(const AZStd::ring_buffer<CpuProfiler::TimeRegionMap>& continuousData);
|
||||
|
||||
AZStd::vector<CpuProfilingStatisticsSerializerEntry> m_cpuProfilingStatisticsSerializerEntries;
|
||||
};
|
||||
|
||||
@@ -6,30 +6,28 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/Feature/Utils/ProfilingCaptureBus.h>
|
||||
#include <Atom/RHI/CpuProfiler.h>
|
||||
#include <Atom/RHI/CpuProfilerImpl.h>
|
||||
#include <Atom/RPI.Edit/Common/JsonUtils.h>
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
#if defined(IMGUI_ENABLED)
|
||||
|
||||
#include <ImGuiCpuProfiler.h>
|
||||
|
||||
#include <CpuProfilerImpl.h>
|
||||
|
||||
#include <AzCore/Casting/lossy_cast.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/JSON/filereadstream.h>
|
||||
#include <AzCore/Statistics/StatisticalProfilerProxy.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerializationResult.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzCore/Statistics/StatisticalProfilerProxy.h>
|
||||
#include <AzCore/std/limits.h>
|
||||
#include <AzCore/std/sort.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/std/time.h>
|
||||
|
||||
|
||||
namespace Profiler
|
||||
{
|
||||
namespace CpuProfilerImGuiHelper
|
||||
{
|
||||
inline float TicksToMs(double ticks)
|
||||
float TicksToMs(double ticks)
|
||||
{
|
||||
// Note: converting to microseconds integer before converting to milliseconds float
|
||||
const AZStd::sys_time_t ticksPerSecond = AZStd::GetTimeTicksPerSecond();
|
||||
@@ -37,27 +35,28 @@ namespace Profiler
|
||||
return static_cast<float>((ticks * 1000) / (ticksPerSecond / 1000)) / 1000.0f;
|
||||
}
|
||||
|
||||
inline float TicksToMs(AZStd::sys_time_t ticks)
|
||||
float TicksToMs(AZStd::sys_time_t ticks)
|
||||
{
|
||||
return TicksToMs(static_cast<double>(ticks));
|
||||
}
|
||||
|
||||
using DeserializedCpuData = AZStd::vector<RHI::CpuProfilingStatisticsSerializer::CpuProfilingStatisticsSerializerEntry>;
|
||||
inline Outcome<DeserializedCpuData, AZStd::string> LoadSavedCpuProfilingStatistics(const AZStd::string& capturePath)
|
||||
{
|
||||
auto* base = IO::FileIOBase::GetInstance();
|
||||
using DeserializedCpuData = AZStd::vector<CpuProfilingStatisticsSerializer::CpuProfilingStatisticsSerializerEntry>;
|
||||
|
||||
char resolvedPath[IO::MaxPathLength];
|
||||
if (!base->ResolvePath(capturePath.c_str(), resolvedPath, IO::MaxPathLength))
|
||||
AZ::Outcome<DeserializedCpuData, AZStd::string> LoadSavedCpuProfilingStatistics(const AZStd::string& capturePath)
|
||||
{
|
||||
auto* base = AZ::IO::FileIOBase::GetInstance();
|
||||
|
||||
char resolvedPath[AZ::IO::MaxPathLength];
|
||||
if (!base->ResolvePath(capturePath.c_str(), resolvedPath, AZ::IO::MaxPathLength))
|
||||
{
|
||||
return Failure(AZStd::string::format("Could not resolve the path to file %s, is the path correct?", resolvedPath));
|
||||
return AZ::Failure(AZStd::string::format("Could not resolve the path to file %s, is the path correct?", resolvedPath));
|
||||
}
|
||||
|
||||
u64 captureSizeBytes;
|
||||
const IO::Result fileSizeResult = base->Size(resolvedPath, captureSizeBytes);
|
||||
AZ::u64 captureSizeBytes;
|
||||
const AZ::IO::Result fileSizeResult = base->Size(resolvedPath, captureSizeBytes);
|
||||
if (!fileSizeResult)
|
||||
{
|
||||
return Failure(AZStd::string::format("Could not read the size of file %s, is the path correct?", resolvedPath));
|
||||
return AZ::Failure(AZStd::string::format("Could not read the size of file %s, is the path correct?", resolvedPath));
|
||||
}
|
||||
|
||||
// NOTE: this uses raw file pointers over the abstractions and utility functions provided by AZ::JsonSerializationUtils because
|
||||
@@ -66,7 +65,7 @@ namespace Profiler
|
||||
azfopen(&fp, resolvedPath, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
return Failure(AZStd::string::format("Could not fopen file %s, is the path correct?\n", resolvedPath));
|
||||
return AZ::Failure(AZStd::string::format("Could not fopen file %s, is the path correct?\n", resolvedPath));
|
||||
}
|
||||
|
||||
constexpr AZStd::size_t MaxBufSize = 65536;
|
||||
@@ -83,37 +82,35 @@ namespace Profiler
|
||||
if (document.HasParseError())
|
||||
{
|
||||
const auto pe = document.GetParseError();
|
||||
return Failure(AZStd::string::format(
|
||||
return AZ::Failure(AZStd::string::format(
|
||||
"Rapidjson could not parse the document with ParseErrorCode %u. See 3rdParty/rapidjson/error.h for definitions.\n", pe));
|
||||
}
|
||||
|
||||
if (!document.IsObject() || !document.HasMember("ClassData"))
|
||||
{
|
||||
return Failure(AZStd::string::format(
|
||||
return AZ::Failure(AZStd::string::format(
|
||||
"Error in loading saved capture: top-level object does not have a ClassData field. Did the serialization format change recently?\n"));
|
||||
}
|
||||
|
||||
AZ_TracePrintf("JsonUtils", "Successfully loaded JSON into memory.\n");
|
||||
|
||||
const auto& root = document["ClassData"];
|
||||
RHI::CpuProfilingStatisticsSerializer serializer;
|
||||
const JsonSerializationResult::ResultCode deserializationResult = JsonSerialization::Load(serializer, root);
|
||||
if (deserializationResult.GetProcessing() == JsonSerializationResult::Processing::Halted
|
||||
CpuProfilingStatisticsSerializer serializer;
|
||||
const AZ::JsonSerializationResult::ResultCode deserializationResult = AZ::JsonSerialization::Load(serializer, root);
|
||||
if (deserializationResult.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted
|
||||
|| serializer.m_cpuProfilingStatisticsSerializerEntries.empty())
|
||||
{
|
||||
return Failure(AZStd::string::format("Error in deserializing document: %s\n", deserializationResult.ToString(capturePath.c_str()).c_str()));
|
||||
return AZ::Failure(AZStd::string::format("Error in deserializing document: %s\n", deserializationResult.ToString(capturePath.c_str()).c_str()));
|
||||
}
|
||||
|
||||
AZ_TracePrintf("JsonUtils", "Successfully loaded CPU profiling data with %zu profiling entries.\n",
|
||||
serializer.m_cpuProfilingStatisticsSerializerEntries.size());
|
||||
|
||||
return Success(AZStd::move(serializer.m_cpuProfilingStatisticsSerializerEntries));
|
||||
return AZ::Success(AZStd::move(serializer.m_cpuProfilingStatisticsSerializerEntries));
|
||||
}
|
||||
} // namespace CpuProfilerImGuiHelper
|
||||
|
||||
|
||||
|
||||
inline void ImGuiCpuProfiler::Draw(bool& keepDrawing)
|
||||
void ImGuiCpuProfiler::Draw(bool& keepDrawing)
|
||||
{
|
||||
// Cache the value to detect if it was changed by ImGui(user pressed 'x')
|
||||
const bool cachedShowCpuProfiler = keepDrawing;
|
||||
@@ -132,9 +129,9 @@ namespace Profiler
|
||||
CullFrameData();
|
||||
|
||||
// Only listen to system ticks when the profiler is active
|
||||
if (!SystemTickBus::Handler::BusIsConnected())
|
||||
if (!AZ::SystemTickBus::Handler::BusIsConnected())
|
||||
{
|
||||
SystemTickBus::Handler::BusConnect();
|
||||
AZ::SystemTickBus::Handler::BusConnect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,27 +156,25 @@ namespace Profiler
|
||||
AZStd::sys_time_t timeNow = AZStd::GetTimeNowSecond();
|
||||
AZStd::string timeString;
|
||||
AZStd::to_string(timeString, timeNow);
|
||||
u64 currentTick = AZ::RPI::RPISystemInterface::Get()->GetCurrentTick();
|
||||
const AZStd::string frameDataFilePath = AZStd::string::format(
|
||||
"@user@/CpuProfiler/%s_%llu.json",
|
||||
timeString.c_str(),
|
||||
currentTick);
|
||||
"@user@/CpuProfiler/%s.json",
|
||||
timeString.c_str());
|
||||
char resolvedPath[AZ::IO::MaxPathLength];
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath(frameDataFilePath.c_str(), resolvedPath, AZ::IO::MaxPathLength);
|
||||
m_lastCapturedFilePath = resolvedPath;
|
||||
AZ::Render::ProfilingCaptureRequestBus::Broadcast(
|
||||
&AZ::Render::ProfilingCaptureRequestBus::Events::CaptureCpuProfilingStatistics, frameDataFilePath);
|
||||
//AZ::Render::ProfilingCaptureRequestBus::Broadcast(
|
||||
// &AZ::Render::ProfilingCaptureRequestBus::Events::CaptureCpuProfilingStatistics, frameDataFilePath);
|
||||
}
|
||||
m_captureToFile = false;
|
||||
|
||||
// Toggle if the bool isn't the same as the cached value
|
||||
if (cachedShowCpuProfiler != keepDrawing)
|
||||
{
|
||||
AZ::RHI::CpuProfiler::Get()->SetProfilerEnabled(keepDrawing);
|
||||
CpuProfiler::Get()->SetProfilerEnabled(keepDrawing);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::DrawCommonHeader()
|
||||
void ImGuiCpuProfiler::DrawCommonHeader()
|
||||
{
|
||||
if (!m_lastCapturedFilePath.empty())
|
||||
{
|
||||
@@ -192,11 +187,11 @@ namespace Profiler
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
m_paused = !AZ::RHI::CpuProfiler::Get()->IsProfilerEnabled();
|
||||
m_paused = !CpuProfiler::Get()->IsProfilerEnabled();
|
||||
if (ImGui::Button(m_paused ? "Resume" : "Pause"))
|
||||
{
|
||||
m_paused = !m_paused;
|
||||
AZ::RHI::CpuProfiler::Get()->SetProfilerEnabled(!m_paused);
|
||||
CpuProfiler::Get()->SetProfilerEnabled(!m_paused);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
@@ -206,7 +201,7 @@ namespace Profiler
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
bool isInProgress = RHI::CpuProfiler::Get()->IsContinuousCaptureInProgress();
|
||||
bool isInProgress = CpuProfiler::Get()->IsContinuousCaptureInProgress();
|
||||
if (ImGui::Button(isInProgress ? "End" : "Begin"))
|
||||
{
|
||||
if (isInProgress)
|
||||
@@ -214,23 +209,21 @@ namespace Profiler
|
||||
AZStd::sys_time_t timeNow = AZStd::GetTimeNowSecond();
|
||||
AZStd::string timeString;
|
||||
AZStd::to_string(timeString, timeNow);
|
||||
u64 currentTick = AZ::RPI::RPISystemInterface::Get()->GetCurrentTick();
|
||||
const AZStd::string frameDataFilePath = AZStd::string::format(
|
||||
"@user@/CpuProfiler/%s_%llu.json",
|
||||
timeString.c_str(),
|
||||
currentTick);
|
||||
"@user@/CpuProfiler/%s.json",
|
||||
timeString.c_str());
|
||||
char resolvedPath[AZ::IO::MaxPathLength];
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath(frameDataFilePath.c_str(), resolvedPath, AZ::IO::MaxPathLength);
|
||||
m_lastCapturedFilePath = resolvedPath;
|
||||
AZ::Render::ProfilingCaptureRequestBus::Broadcast(
|
||||
&AZ::Render::ProfilingCaptureRequestBus::Events::EndContinuousCpuProfilingCapture, frameDataFilePath);
|
||||
//AZ::Render::ProfilingCaptureRequestBus::Broadcast(
|
||||
// &AZ::Render::ProfilingCaptureRequestBus::Events::EndContinuousCpuProfilingCapture, frameDataFilePath);
|
||||
m_paused = true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
AZ::Render::ProfilingCaptureRequestBus::Broadcast(
|
||||
&AZ::Render::ProfilingCaptureRequestBus::Events::BeginContinuousCpuProfilingCapture);
|
||||
//AZ::Render::ProfilingCaptureRequestBus::Broadcast(
|
||||
// &AZ::Render::ProfilingCaptureRequestBus::Events::BeginContinuousCpuProfilingCapture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,21 +241,21 @@ namespace Profiler
|
||||
defaultSavedCapturePath.c_str(), "*.json",
|
||||
[&paths = m_cachedCapturePaths](const char* path) -> bool
|
||||
{
|
||||
auto foundPath = IO::Path(path);
|
||||
auto foundPath = AZ::IO::Path(path);
|
||||
paths.push_back(foundPath);
|
||||
return true;
|
||||
});
|
||||
|
||||
// Sort by decreasing modification time (most recent at the top)
|
||||
AZStd::sort(m_cachedCapturePaths.begin(), m_cachedCapturePaths.end(),
|
||||
[&base](const IO::Path& lhs, const IO::Path& rhs)
|
||||
[&base](const AZ::IO::Path& lhs, const AZ::IO::Path& rhs)
|
||||
{
|
||||
return base->ModificationTime(lhs.c_str()) > base->ModificationTime(rhs.c_str());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::DrawTable()
|
||||
void ImGuiCpuProfiler::DrawTable()
|
||||
{
|
||||
const auto flags =
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_Sortable | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable;
|
||||
@@ -326,7 +319,7 @@ namespace Profiler
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::SortTable(ImGuiTableSortSpecs* sortSpecs)
|
||||
void ImGuiCpuProfiler::SortTable(ImGuiTableSortSpecs* sortSpecs)
|
||||
{
|
||||
const bool ascending = sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending;
|
||||
const ImS16 columnToSort = sortSpecs->Specs->ColumnIndex;
|
||||
@@ -355,7 +348,7 @@ namespace Profiler
|
||||
sortSpecs->SpecsDirty = false;
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::DrawStatisticsView()
|
||||
void ImGuiCpuProfiler::DrawStatisticsView()
|
||||
{
|
||||
DrawCommonHeader();
|
||||
|
||||
@@ -400,7 +393,7 @@ namespace Profiler
|
||||
}
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::DrawFilePicker()
|
||||
void ImGuiCpuProfiler::DrawFilePicker()
|
||||
{
|
||||
ImGui::SetNextWindowSize({ 500, 200 }, ImGuiCond_Once);
|
||||
if (ImGui::Begin("File Picker", &m_showFilePicker))
|
||||
@@ -412,7 +405,7 @@ namespace Profiler
|
||||
|
||||
auto getter = [](void* vectorPointer, int idx, const char** out_text) -> bool
|
||||
{
|
||||
const auto& pathVec = *static_cast<AZStd::vector<IO::Path>*>(vectorPointer);
|
||||
const auto& pathVec = *static_cast<AZStd::vector<AZ::IO::Path>*>(vectorPointer);
|
||||
if (idx < 0 || idx >= pathVec.size())
|
||||
{
|
||||
return false;
|
||||
@@ -427,9 +420,9 @@ namespace Profiler
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::LoadFile()
|
||||
void ImGuiCpuProfiler::LoadFile()
|
||||
{
|
||||
const IO::Path& pathToLoad = m_cachedCapturePaths[m_currentFileIndex];
|
||||
const AZ::IO::Path& pathToLoad = m_cachedCapturePaths[m_currentFileIndex];
|
||||
auto loadResult = CpuProfilerImGuiHelper::LoadSavedCpuProfilingStatistics(pathToLoad.String());
|
||||
if (!loadResult.IsSuccess())
|
||||
{
|
||||
@@ -437,13 +430,14 @@ namespace Profiler
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::vector<RHI::CpuProfilingStatisticsSerializer::CpuProfilingStatisticsSerializerEntry> deserializedData = loadResult.TakeValue();
|
||||
AZStd::vector<CpuProfilingStatisticsSerializer::CpuProfilingStatisticsSerializerEntry> deserializedData = loadResult.TakeValue();
|
||||
|
||||
// Clear visualizer and statistics view state
|
||||
m_savedRegionCount = deserializedData.size();
|
||||
m_savedData.clear();
|
||||
m_paused = true;
|
||||
AZ::RHI::CpuProfiler::Get()->SetProfilerEnabled(false);
|
||||
|
||||
CpuProfiler::Get()->SetProfilerEnabled(false);
|
||||
m_frameEndTicks.clear();
|
||||
|
||||
m_tableData.clear();
|
||||
@@ -456,11 +450,11 @@ namespace Profiler
|
||||
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 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.
|
||||
const static Name frameBoundaryName = Name("RPISystem: OnSystemTick");
|
||||
const static AZ::Name frameBoundaryName = AZ::Name("RPISystem: OnSystemTick");
|
||||
if (entry.m_regionName == frameBoundaryName)
|
||||
{
|
||||
m_frameEndTicks.push_back(entry.m_endTick);
|
||||
@@ -492,7 +486,7 @@ namespace Profiler
|
||||
}
|
||||
|
||||
// -- CPU Visualizer --
|
||||
inline void ImGuiCpuProfiler::DrawVisualizer()
|
||||
void ImGuiCpuProfiler::DrawVisualizer()
|
||||
{
|
||||
DrawCommonHeader();
|
||||
|
||||
@@ -556,7 +550,7 @@ namespace Profiler
|
||||
}
|
||||
|
||||
// Main draw loop
|
||||
u64 baseRow = 0;
|
||||
AZ::u64 baseRow = 0;
|
||||
for (const auto& [currentThreadId, singleThreadData] : m_savedData)
|
||||
{
|
||||
// Find the first TimeRegion that we should draw
|
||||
@@ -573,7 +567,7 @@ namespace Profiler
|
||||
}
|
||||
|
||||
// Draw all of the blocks for a given thread/row
|
||||
u64 maxDepth = 0;
|
||||
AZ::u64 maxDepth = 0;
|
||||
while (regionItr != singleThreadData.end())
|
||||
{
|
||||
const TimeRegion& region = *regionItr;
|
||||
@@ -583,8 +577,8 @@ namespace Profiler
|
||||
{
|
||||
break;
|
||||
}
|
||||
u64 targetRow = region.m_stackDepth + baseRow;
|
||||
maxDepth = AZStd::max(aznumeric_cast<u64>(region.m_stackDepth), maxDepth);
|
||||
AZ::u64 targetRow = region.m_stackDepth + baseRow;
|
||||
maxDepth = AZStd::max(aznumeric_cast<AZ::u64>(region.m_stackDepth), maxDepth);
|
||||
|
||||
DrawBlock(region, targetRow);
|
||||
|
||||
@@ -649,7 +643,7 @@ namespace Profiler
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::CacheCpuTimingStatistics()
|
||||
void ImGuiCpuProfiler::CacheCpuTimingStatistics()
|
||||
{
|
||||
using namespace AZ::Statistics;
|
||||
|
||||
@@ -675,7 +669,7 @@ namespace Profiler
|
||||
}
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::CollectFrameData()
|
||||
void ImGuiCpuProfiler::CollectFrameData()
|
||||
{
|
||||
// We maintain separate datastores for the visualizer and the statistical view because they require different
|
||||
// data formats - one grouped by thread ID versus the other organized by group + region. Since the statistical
|
||||
@@ -683,10 +677,10 @@ namespace Profiler
|
||||
// compared to if we needed to transform the visualizer's data into the statistical format every frame.
|
||||
|
||||
// Get the latest TimeRegionMap
|
||||
const RHI::CpuProfiler::TimeRegionMap& timeRegionMap = RHI::CpuProfiler::Get()->GetTimeRegionMap();
|
||||
const CpuProfiler::TimeRegionMap& timeRegionMap = CpuProfiler::Get()->GetTimeRegionMap();
|
||||
|
||||
m_viewportStartTick = AZStd::numeric_limits<s64>::max();
|
||||
m_viewportEndTick = AZStd::numeric_limits<s64>::lowest();
|
||||
m_viewportStartTick = AZStd::numeric_limits<AZ::s64>::max();
|
||||
m_viewportEndTick = AZStd::numeric_limits<AZ::s64>::lowest();
|
||||
|
||||
// Iterate through the entire TimeRegionMap and copy the data since it will get deleted on the next frame
|
||||
for (const auto& [threadId, singleThreadRegionMap] : timeRegionMap)
|
||||
@@ -743,7 +737,7 @@ namespace Profiler
|
||||
}
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::CullFrameData()
|
||||
void ImGuiCpuProfiler::CullFrameData()
|
||||
{
|
||||
const AZStd::sys_time_t deleteBeforeTick = AZStd::GetTimeNowTicks() - m_frameToFrameTime * m_framesToCollect;
|
||||
|
||||
@@ -783,7 +777,7 @@ namespace Profiler
|
||||
});
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::DrawBlock(const TimeRegion& block, u64 targetRow)
|
||||
void ImGuiCpuProfiler::DrawBlock(const TimeRegion& block, AZ::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))
|
||||
@@ -864,7 +858,7 @@ namespace Profiler
|
||||
}
|
||||
}
|
||||
|
||||
inline ImU32 ImGuiCpuProfiler::GetBlockColor(const TimeRegion& block)
|
||||
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;
|
||||
@@ -874,7 +868,7 @@ namespace Profiler
|
||||
}
|
||||
|
||||
// Cache miss, generate a new random color
|
||||
AZ::SimpleLcgRandom rand(aznumeric_cast<u64>(AZStd::GetTimeNowTicks()));
|
||||
AZ::SimpleLcgRandom rand(aznumeric_cast<AZ::u64>(AZStd::GetTimeNowTicks()));
|
||||
const float r = AZStd::clamp(rand.GetRandomFloat(), .1f, .9f);
|
||||
const float g = AZStd::clamp(rand.GetRandomFloat(), .1f, .9f);
|
||||
const float b = AZStd::clamp(rand.GetRandomFloat(), .1f, .9f);
|
||||
@@ -883,7 +877,7 @@ namespace Profiler
|
||||
return ImGui::GetColorU32(randomColor);
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::DrawThreadSeparator(u64 baseRow, u64 maxDepth)
|
||||
void ImGuiCpuProfiler::DrawThreadSeparator(AZ::u64 baseRow, AZ::u64 maxDepth)
|
||||
{
|
||||
const ImU32 red = ImGui::GetColorU32({ 1, 0, 0, 1 });
|
||||
|
||||
@@ -895,7 +889,7 @@ namespace Profiler
|
||||
ImGui::GetWindowDrawList()->AddLine({ wx, boundaryY }, { wx + windowWidth, boundaryY }, red, 1.0f);
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::DrawThreadLabel(u64 baseRow, size_t threadId)
|
||||
void ImGuiCpuProfiler::DrawThreadLabel(AZ::u64 baseRow, size_t threadId)
|
||||
{
|
||||
auto [wx, wy] = ImGui::GetWindowPos();
|
||||
wy -= ImGui::GetScrollY();
|
||||
@@ -904,7 +898,7 @@ namespace Profiler
|
||||
ImGui::GetWindowDrawList()->AddText({ wx + 10, wy + baseRow * RowHeight}, IM_COL32_WHITE, threadIdText.c_str());
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::DrawFrameBoundaries()
|
||||
void ImGuiCpuProfiler::DrawFrameBoundaries()
|
||||
{
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
|
||||
@@ -923,7 +917,7 @@ namespace Profiler
|
||||
}
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::DrawRuler()
|
||||
void ImGuiCpuProfiler::DrawRuler()
|
||||
{
|
||||
// Use a pair of iterators to go through all saved frame boundaries and draw ruler lines
|
||||
auto lastFrameBoundaryItr = AZStd::lower_bound(m_frameEndTicks.begin(), m_frameEndTicks.end(), m_viewportStartTick);
|
||||
@@ -1001,7 +995,7 @@ namespace Profiler
|
||||
}
|
||||
}
|
||||
|
||||
inline void ImGuiCpuProfiler::DrawFrameTimeHistogram()
|
||||
void ImGuiCpuProfiler::DrawFrameTimeHistogram()
|
||||
{
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
const auto [wx, wy] = ImGui::GetWindowPos();
|
||||
@@ -1083,12 +1077,12 @@ namespace Profiler
|
||||
}
|
||||
}
|
||||
|
||||
inline AZStd::sys_time_t ImGuiCpuProfiler::GetViewportTickWidth() const
|
||||
AZStd::sys_time_t ImGuiCpuProfiler::GetViewportTickWidth() const
|
||||
{
|
||||
return m_viewportEndTick - m_viewportStartTick;
|
||||
}
|
||||
|
||||
inline float ImGuiCpuProfiler::ConvertTickToPixelSpace(AZStd::sys_time_t tick, AZStd::sys_time_t leftBound, AZStd::sys_time_t rightBound) const
|
||||
float ImGuiCpuProfiler::ConvertTickToPixelSpace(AZStd::sys_time_t tick, AZStd::sys_time_t leftBound, AZStd::sys_time_t rightBound) const
|
||||
{
|
||||
const float wx = ImGui::GetWindowPos().x;
|
||||
const float tickSpaceShifted = aznumeric_cast<float>(tick - leftBound); // This will be close to zero, so FP inaccuracy should not be too bad
|
||||
@@ -1098,11 +1092,11 @@ namespace Profiler
|
||||
}
|
||||
|
||||
// System tick bus overrides
|
||||
inline void ImGuiCpuProfiler::OnSystemTick()
|
||||
void ImGuiCpuProfiler::OnSystemTick()
|
||||
{
|
||||
if (m_paused)
|
||||
{
|
||||
SystemTickBus::Handler::BusDisconnect();
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1120,7 +1114,7 @@ namespace Profiler
|
||||
|
||||
// ---- TableRow impl ----
|
||||
|
||||
inline void TableRow::RecordRegion(const AZ::RHI::CachedTimeRegion& region, size_t threadId)
|
||||
void TableRow::RecordRegion(const CachedTimeRegion& region, size_t threadId)
|
||||
{
|
||||
const AZStd::sys_time_t deltaTime = region.m_endTick - region.m_startTick;
|
||||
|
||||
@@ -1136,7 +1130,7 @@ namespace Profiler
|
||||
++m_invocationsTotal;
|
||||
}
|
||||
|
||||
inline void TableRow::ResetPerFrameStatistics()
|
||||
void TableRow::ResetPerFrameStatistics()
|
||||
{
|
||||
m_invocationsLastFrame = 0;
|
||||
m_executingThreads.clear();
|
||||
@@ -1144,7 +1138,7 @@ namespace Profiler
|
||||
m_maxTicks = 0;
|
||||
}
|
||||
|
||||
inline AZStd::string TableRow::GetExecutingThreadsLabel() const
|
||||
AZStd::string TableRow::GetExecutingThreadsLabel() const
|
||||
{
|
||||
auto threadString = AZStd::string::format("Executed in %zu threads\n", m_executingThreads.size());
|
||||
for (const auto& threadId : m_executingThreads)
|
||||
@@ -1154,3 +1148,5 @@ namespace Profiler
|
||||
return threadString;
|
||||
}
|
||||
} // namespace Profiler
|
||||
|
||||
#endif // defined(IMGUI_ENABLED)
|
||||
|
||||
@@ -8,12 +8,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(IMGUI_ENABLED)
|
||||
|
||||
#include <CpuProfiler.h>
|
||||
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Math/Random.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
|
||||
#include <Atom/RHI/CpuProfiler.h>
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
namespace Profiler
|
||||
{
|
||||
@@ -35,7 +41,7 @@ namespace Profiler
|
||||
};
|
||||
|
||||
// Update running statistics with new region data
|
||||
void RecordRegion(const AZ::RHI::CachedTimeRegion& region, size_t threadId);
|
||||
void RecordRegion(const CachedTimeRegion& region, size_t threadId);
|
||||
|
||||
void ResetPerFrameStatistics();
|
||||
|
||||
@@ -47,7 +53,7 @@ namespace Profiler
|
||||
|
||||
// --- Per frame statistics ---
|
||||
|
||||
u64 m_invocationsLastFrame = 0;
|
||||
AZ::u64 m_invocationsLastFrame = 0;
|
||||
|
||||
// NOTE: set over unordered_set so the threads can be shown in increasing order in tooltip.
|
||||
AZStd::set<size_t> m_executingThreads;
|
||||
@@ -59,7 +65,7 @@ namespace Profiler
|
||||
|
||||
// --- Aggregate statistics ---
|
||||
|
||||
u64 m_invocationsTotal = 0;
|
||||
AZ::u64 m_invocationsTotal = 0;
|
||||
|
||||
// Running average of Mean Time Per Call
|
||||
AZStd::sys_time_t m_runningAverageTicks = 0;
|
||||
@@ -69,15 +75,15 @@ namespace Profiler
|
||||
//! Offers both a statistical view (with sorting and searching capability) and a visualizer
|
||||
//! similar to RAD and other profiling tools.
|
||||
class ImGuiCpuProfiler
|
||||
: SystemTickBus::Handler
|
||||
: public AZ::SystemTickBus::Handler
|
||||
{
|
||||
// Region Name -> statistical view row data
|
||||
using RegionRowMap = AZStd::map<AZStd::string, TableRow>;
|
||||
// Group Name -> RegionRowMap
|
||||
using GroupRegionMap = AZStd::map<AZStd::string, RegionRowMap>;
|
||||
|
||||
using TimeRegion = AZ::RHI::CachedTimeRegion;
|
||||
using GroupRegionName = AZ::RHI::CachedTimeRegion::GroupRegionName;
|
||||
using TimeRegion = CachedTimeRegion;
|
||||
using GroupRegionName = CachedTimeRegion::GroupRegionName;
|
||||
|
||||
public:
|
||||
struct CpuTimingEntry
|
||||
@@ -129,13 +135,13 @@ namespace Profiler
|
||||
void CullFrameData();
|
||||
|
||||
// Draws a single block onto the timeline into the specified row
|
||||
void DrawBlock(const TimeRegion& block, u64 targetRow);
|
||||
void DrawBlock(const TimeRegion& block, AZ::u64 targetRow);
|
||||
|
||||
// Draw horizontal lines between threads in the timeline
|
||||
void DrawThreadSeparator(u64 threadBoundary, u64 maxDepth);
|
||||
void DrawThreadSeparator(AZ::u64 threadBoundary, AZ::u64 maxDepth);
|
||||
|
||||
// Draw the "Thread XXXXX" label onto the viewport
|
||||
void DrawThreadLabel(u64 baseRow, size_t threadId);
|
||||
void DrawThreadLabel(AZ::u64 baseRow, size_t threadId);
|
||||
|
||||
// Draw the vertical lines separating frames in the timeline
|
||||
void DrawFrameBoundaries();
|
||||
@@ -156,14 +162,14 @@ namespace Profiler
|
||||
ImU32 GetBlockColor(const TimeRegion& block);
|
||||
|
||||
// System tick bus overrides
|
||||
virtual void OnSystemTick() override;
|
||||
void OnSystemTick() override;
|
||||
|
||||
// --- Visualizer Members ---
|
||||
|
||||
int m_framesToCollect = DefaultFramesToCollect;
|
||||
|
||||
// Tally of the number of saved profiling events so far
|
||||
u64 m_savedRegionCount = 0;
|
||||
AZ::u64 m_savedRegionCount = 0;
|
||||
|
||||
// Viewport tick bounds, these are used to convert tick space -> screen space and cull so we only draw onscreen objects
|
||||
AZStd::sys_time_t m_viewportStartTick;
|
||||
@@ -175,7 +181,7 @@ namespace Profiler
|
||||
AZStd::unordered_map<size_t, AZStd::vector<TimeRegion>> m_savedData;
|
||||
|
||||
// Region color cache
|
||||
AZStd::unordered_map<GroupRegionName, ImVec4, RHI::CachedTimeRegion::GroupRegionName::Hash> m_regionColorMap;
|
||||
AZStd::unordered_map<GroupRegionName, ImVec4, CachedTimeRegion::GroupRegionName::Hash> m_regionColorMap;
|
||||
|
||||
// Tracks the frame boundaries
|
||||
AZStd::vector<AZStd::sys_time_t> m_frameEndTicks = { INT64_MIN };
|
||||
@@ -213,7 +219,7 @@ namespace Profiler
|
||||
bool m_showFilePicker = false;
|
||||
|
||||
// Cached file paths to previous traces on disk, sorted with the most recent trace at the front.
|
||||
AZStd::vector<IO::Path> m_cachedCapturePaths;
|
||||
AZStd::vector<AZ::IO::Path> m_cachedCapturePaths;
|
||||
|
||||
// Index into the file picker, used to determine which file to load when "Load File" is pressed.
|
||||
int m_currentFileIndex = 0;
|
||||
@@ -221,8 +227,8 @@ namespace Profiler
|
||||
|
||||
// --- Loading capture state ---
|
||||
AZStd::unordered_set<AZStd::string> m_deserializedStringPool;
|
||||
AZStd::unordered_set<RHI::CachedTimeRegion::GroupRegionName, RHI::CachedTimeRegion::GroupRegionName::Hash> m_deserializedGroupRegionNamePool;
|
||||
AZStd::unordered_set<CachedTimeRegion::GroupRegionName, CachedTimeRegion::GroupRegionName::Hash> m_deserializedGroupRegionNamePool;
|
||||
};
|
||||
} // namespace Profiler
|
||||
|
||||
#include "ImGuiCpuProfiler.inl"
|
||||
#endif // defined(IMGUI_ENABLED)
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
|
||||
set(FILES
|
||||
Include/Profiler/ProfilerBus.h
|
||||
Source/CpuProfiler.h
|
||||
Source/CpuProfilerImpl.cpp
|
||||
Source/CpuProfilerImpl.h
|
||||
Source/ImGuiCpuProfiler.cpp
|
||||
Source/ImGuiCpuProfiler.h
|
||||
Source/ProfilerModuleInterface.h
|
||||
Source/ProfilerSystemComponent.cpp
|
||||
Source/ProfilerSystemComponent.h
|
||||
|
||||
Reference in New Issue
Block a user