PerformanceCVarManager.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Debug/PerformanceCollector.h>
  9. #include <Atom/RPI.Public/Pass/PassSystemInterface.h>
  10. #include <Atom/RPI.Public/Pass/ParentPass.h>
  11. #include <Atom/RPI.Public/GpuQuery/GpuPassProfiler.h>
  12. #include "PerformanceCVarManager.h"
  13. namespace AZ
  14. {
  15. namespace RPI
  16. {
  17. AZ_CVAR(AZ::CVarFixedString, r_metricsDataLogType,
  18. "statistical", // (s)(S)tatistical Summary (average, min, max, stdev) / (a)(A)ll Samples. Default=s.
  19. nullptr, //&PerformanceCvarManager::OnDataLogTypeChanged,
  20. ConsoleFunctorFlags::DontReplicate,
  21. "Defines the kind of data collection and logging. If starts with 's' it will log statistical summaries, if starts with 'a' will log each sample of data (high verbosity).");
  22. AZ_CVAR(AZ::u32, r_metricsWaitTimePerCaptureBatch,
  23. 0, // Starts at 0, which means "do not wait before starting to capture performance data".
  24. nullptr, //&PerformanceCvarManager::OnWaitTimePerCaptureBatchChanged,
  25. ConsoleFunctorFlags::DontReplicate,
  26. "How many seconds to wait before each batch of performance capture.");
  27. AZ_CVAR(AZ::u32, r_metricsFrameCountPerCaptureBatch,
  28. 1200, // Number of frames in which performance will be measured per batch.
  29. nullptr, //&PerformanceCvarManager::OnFrameCountPerCaptureBatchChanged,
  30. ConsoleFunctorFlags::DontReplicate,
  31. "Number of frames in which performance will be measured per batch.");
  32. // "Frame Gpu Time" is the only gated performance metric because it takes a considerable amount
  33. // of CPU time. For example, when NOT capturing this metric, the default level runs at 300fps on a GTX 3070,
  34. // if this metric is enabled, the FPS drops to 270. It is recommended that this metric is captured in isolation
  35. // so it doesn't affect the results of the "Engine Cpu Time" metric.
  36. AZ_CVAR(bool, r_metricsMeasureGpuTime,
  37. false,
  38. nullptr,
  39. ConsoleFunctorFlags::DontReplicate,
  40. "If true, The Frame Gpu Time is measured. By default it is false, as this measurement is CPU expensive.");
  41. AZ_CVAR(bool, r_metricsQuitUponCompletion,
  42. false, // If true the application will quit when Number Of Capture Batches reaches 0.
  43. nullptr,
  44. ConsoleFunctorFlags::DontReplicate,
  45. "If true the application will quit when Number Of Capture Batches reaches 0.");
  46. AZ::Debug::PerformanceCollector::DataLogType GetDataLogTypeFromCVar(const AZ::CVarFixedString& newCaptureType)
  47. {
  48. if (newCaptureType.starts_with('a') || newCaptureType.starts_with('A'))
  49. {
  50. return AZ::Debug::PerformanceCollector::DataLogType::LogAllSamples;
  51. }
  52. return AZ::Debug::PerformanceCollector::DataLogType::LogStatistics;
  53. }
  54. class PerformanceCvarManager
  55. {
  56. public:
  57. static constexpr char LogName[] = "RPIPerformanceCvarManager";
  58. static void OnNumberOfCaptureBatchesChanged(const AZ::u32& newValue)
  59. {
  60. AZ_TracePrintf(LogName, "%s cvar changed to %u.\n", __FUNCTION__, newValue);
  61. auto performanceCollectorOwner = PerformanceCollectorOwner::Get();
  62. if (!performanceCollectorOwner)
  63. {
  64. return;
  65. }
  66. auto performanceCollector = performanceCollectorOwner->GetPerformanceCollector();
  67. if (!performanceCollector)
  68. {
  69. return;
  70. }
  71. // For diagnostics purposes write to the log the state of the CVars involved
  72. // in Graphics performance collection.
  73. CVarFixedString metricsDataLogType = r_metricsDataLogType;
  74. AZ_TracePrintf(LogName, "%s r_metricsDataLogType=%s.\n", __FUNCTION__, metricsDataLogType.c_str());
  75. AZ::u32 metricsWaitTimePerCaptureBatch = r_metricsWaitTimePerCaptureBatch;
  76. AZ_TracePrintf(LogName, "%s r_metricsWaitTimePerCaptureBatch=%u.\n", __FUNCTION__, metricsWaitTimePerCaptureBatch);
  77. AZ::u32 metricsFrameCountPerCaptureBatch = r_metricsFrameCountPerCaptureBatch;
  78. AZ_TracePrintf(LogName, "%s r_metricsFrameCountPerCaptureBatch=%u.\n", __FUNCTION__, metricsFrameCountPerCaptureBatch);
  79. bool metricsMeasureGpuTime = r_metricsMeasureGpuTime;
  80. AZ_TracePrintf(LogName, "%s value of r_metricsMeasureGpuTime=%s.\n", __FUNCTION__, metricsMeasureGpuTime ? "true" : "false");
  81. [[maybe_unused]] bool metricsQuitUponCompletion = r_metricsQuitUponCompletion;
  82. AZ_TracePrintf(LogName, "%s value of r_metricsQuitUponCompletion=%s.\n", __FUNCTION__, metricsQuitUponCompletion ? "true" : "false");
  83. auto gpuPassProfiler = performanceCollectorOwner->GetGpuPassProfiler();
  84. if (gpuPassProfiler)
  85. {
  86. gpuPassProfiler->SetGpuTimeMeasurementEnabled(metricsMeasureGpuTime);
  87. }
  88. performanceCollector->UpdateDataLogType(GetDataLogTypeFromCVar(metricsDataLogType));
  89. performanceCollector->UpdateWaitTimeBeforeEachBatch(AZStd::chrono::seconds(metricsWaitTimePerCaptureBatch));
  90. performanceCollector->UpdateFrameCountPerCaptureBatch(metricsFrameCountPerCaptureBatch);
  91. performanceCollector->UpdateNumberOfCaptureBatches(newValue);
  92. }
  93. };
  94. AZ_CVAR(AZ::u32, r_metricsNumberOfCaptureBatches,
  95. 0, // Starts at 0, which means "do not capture performance data". When this variable changes to >0 we'll start performance capture.
  96. &PerformanceCvarManager::OnNumberOfCaptureBatchesChanged,
  97. ConsoleFunctorFlags::DontReplicate,
  98. "Collects and reports graphics performance in this number of batches.");
  99. } // namespace RPI
  100. } // namespace AZ