OutputProfileData.lua 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. ----------------------------------------------------------------------------------------------------
  2. --
  3. -- Copyright (c) Contributors to the Open 3D Engine Project.
  4. -- For complete copyright and license terms please see the LICENSE at the root of this distribution.
  5. --
  6. -- SPDX-License-Identifier: Apache-2.0 OR MIT
  7. --
  8. --
  9. --
  10. ----------------------------------------------------------------------------------------------------
  11. local OutputProfileData =
  12. {
  13. Properties =
  14. {
  15. FrameDelayCount = 100,
  16. FrameCaptureCount = 100,
  17. ProfileName = "LevelFrameTiming",
  18. QuitOnComplete = true,
  19. },
  20. frameCount = 0,
  21. frameDelayCount = 0,
  22. frameCaptureCount = 0,
  23. captureCount = 0,
  24. quitOnComplete = false,
  25. profileName = "UninitializedName",
  26. outputFolder = "UninitializedPath",
  27. cpuTimingsOutputPath = "UninitializedPath",
  28. captureInProgress = false,
  29. active = false,
  30. };
  31. local FrameTimeRecordingActiveRegistryKey <const> = "/O3DE/Performance/FrameTimeRecording/Activate"
  32. local FrameDelayCountRegistryKey <const> = "/O3DE/Performance/FrameTimeRecording/DelayCount"
  33. local FrameCaptureCountRegistryKey <const> = "/O3DE/Performance/FrameTimeRecording/CaptureCount"
  34. local ProfileNameRegistryKey <const> = "/O3DE/Performance/FrameTimeRecording/ProfileName"
  35. local QuitOnCompleteRegistryKey <const> = "/O3DE/Performance/FrameTimeRecording/QuitOnComplete"
  36. local SourceProjectUserPathRegistryKey <const> = "/O3DE/Runtime/FilePaths/SourceProjectUserPath"
  37. local ConsoleCommandQuitRegistryKey <const> = "/Amazon/AzCore/Runtime/ConsoleCommands/quit"
  38. function OutputProfileData:TryDisconnect()
  39. self.profileCaptureNotificationHandler:Disconnect()
  40. self.tickHandler:Disconnect()
  41. end
  42. function OutputProfileData:TryQuitOnComplete()
  43. if (self.quitOnComplete) then
  44. g_SettingsRegistry:SetString(ConsoleCommandQuitRegistryKey, "")
  45. end
  46. end
  47. function OutputProfileData:TryCapture()
  48. self.captureInProgress = true
  49. self.cpuTimingsOutputPath = tostring(self.outputFolder) .. '/cpu_frame' .. tostring(self.captureCount) .. '_time.json'
  50. ProfilingCaptureRequestBus.Broadcast.CaptureCpuFrameTime(self.cpuTimingsOutputPath)
  51. end
  52. function OutputProfileData:CaptureFinished()
  53. self.captureInProgress = false
  54. end
  55. function OutputProfileData:OnActivate()
  56. if (g_SettingsRegistry:IsValid()) then
  57. local quitOnCompleteValue = g_SettingsRegistry:GetBool(QuitOnCompleteRegistryKey)
  58. self.quitOnComplete = quitOnCompleteValue:value_or(self.Properties.QuitOnComplete)
  59. local frameTimeRecordingActivateValue = g_SettingsRegistry:GetBool(FrameTimeRecordingActiveRegistryKey)
  60. if (not frameTimeRecordingActivateValue:has_value() or not frameTimeRecordingActivateValue:value()) then
  61. Debug:Log("OutputProfileData:OnActivate - Missing registry setting to activate frame time recording, aborting data collection")
  62. return
  63. end
  64. -- get path to user folder
  65. local pathToUserFolder = "InvalidPath/"
  66. local settingsRegistryResult = g_SettingsRegistry:GetString(SourceProjectUserPathRegistryKey)
  67. if (settingsRegistryResult:has_value()) then
  68. pathToUserFolder = settingsRegistryResult:value()
  69. else
  70. Debug:Log("OutputProfileData:OnActivate - Unable to resolve the SourceProjectUserPath, aborting data collection")
  71. self:TryQuitOnComplete()
  72. return
  73. end
  74. -- get any registry property overrides
  75. local frameDelayCountValue = g_SettingsRegistry:GetUInt(FrameDelayCountRegistryKey)
  76. self.frameDelayCount = frameDelayCountValue:value_or(self.Properties.FrameDelayCount)
  77. local frameCaptureCountValue = g_SettingsRegistry:GetUInt(FrameCaptureCountRegistryKey)
  78. self.frameCaptureCount = frameCaptureCountValue:value_or(self.Properties.FrameCaptureCount)
  79. local profileNameValue = g_SettingsRegistry:GetString(ProfileNameRegistryKey)
  80. self.profileName = profileNameValue:value_or(self.Properties.ProfileName)
  81. -- generate final output path string
  82. self.outputFolder = tostring(pathToUserFolder) .. "/Scripts/PerformanceBenchmarks/" .. tostring(self.profileName)
  83. -- register for ebus callbacks
  84. self.tickHandler = TickBus.Connect(self)
  85. self.profileCaptureNotificationHandler = ProfilingCaptureNotificationBus.Connect(self)
  86. -- output test metadata
  87. ProfilingCaptureRequestBus.Broadcast.CaptureBenchmarkMetadata(
  88. self.profileName, tostring(self.outputFolder) .. "/benchmark_metadata.json")
  89. end
  90. end
  91. function OutputProfileData:OnTick()
  92. if (not self.active) then -- wait for benchmark metadata to get written before starting
  93. return
  94. end
  95. self.frameCount = self.frameCount + 1
  96. if (self.frameCount <= self.frameDelayCount) then
  97. return
  98. end
  99. if (self.captureCount < self.frameCaptureCount and not self.captureInProgress) then
  100. self.captureCount = self.captureCount + 1
  101. self:TryCapture()
  102. elseif (self.captureCount >= self.frameCaptureCount and not self.captureInProgress) then
  103. Debug:Log("OutputProfileData complete")
  104. self:TryDisconnect()
  105. self:TryQuitOnComplete()
  106. end
  107. end
  108. function OutputProfileData:OnCaptureCpuFrameTimeFinished(successful, capture_output_path)
  109. if (self.captureInProgress and self.cpuTimingsOutputPath == capture_output_path) then
  110. self:CaptureFinished()
  111. end
  112. end
  113. function OutputProfileData:OnCaptureBenchmarkMetadataFinished(successful, info)
  114. if (not successful) then
  115. Debug:Log("OutputProfileData - Failed to capture benchmark metadata, aborting data collection")
  116. -- force profile to end asap without trying to record
  117. self.frameCount = self.frameDelayCount
  118. self.captureCount = self.FrameCaptureCount
  119. self:TryDisconnect()
  120. self:TryQuitOnComplete()
  121. else
  122. self.active = true
  123. end
  124. end
  125. function OutputProfileData:OnDeactivate()
  126. self:TryDisconnect()
  127. end
  128. return OutputProfileData