benchmark_utils.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. SPDX-License-Identifier: Apache-2.0 OR MIT
  5. """
  6. import azlmbr.atom
  7. import azlmbr.legacy.general as general
  8. FOLDER_PATH = '@user@/Scripts/PerformanceBenchmarks'
  9. METADATA_FILE = 'benchmark_metadata.json'
  10. class BenchmarkHelper(object):
  11. """
  12. A helper to capture benchmark data.
  13. """
  14. def __init__(self, benchmark_name):
  15. super().__init__()
  16. self.benchmark_name = benchmark_name
  17. self.output_path = f'{FOLDER_PATH}/{benchmark_name}'
  18. self.done = False
  19. self.capturedData = False
  20. self.max_frames_to_wait = 200
  21. def capture_benchmark_metadata(self):
  22. """
  23. Capture benchmark metadata and block further execution until it has been written to the disk.
  24. """
  25. self.handler = azlmbr.atom.ProfilingCaptureNotificationBusHandler()
  26. self.handler.connect()
  27. self.handler.add_callback('OnCaptureBenchmarkMetadataFinished', self.on_data_captured)
  28. self.done = False
  29. self.capturedData = False
  30. success = azlmbr.atom.ProfilingCaptureRequestBus(
  31. azlmbr.bus.Broadcast, "CaptureBenchmarkMetadata", self.benchmark_name, f'{self.output_path}/{METADATA_FILE}'
  32. )
  33. if success:
  34. self.wait_until_data()
  35. general.log('Benchmark metadata captured.')
  36. else:
  37. general.log('Failed to capture benchmark metadata.')
  38. return self.capturedData
  39. def capture_pass_timestamp(self, frame_number):
  40. """
  41. Capture pass timestamps and block further execution until it has been written to the disk.
  42. """
  43. self.handler = azlmbr.atom.ProfilingCaptureNotificationBusHandler()
  44. self.handler.connect()
  45. self.handler.add_callback('OnCaptureQueryTimestampFinished', self.on_data_captured)
  46. self.done = False
  47. self.capturedData = False
  48. success = azlmbr.atom.ProfilingCaptureRequestBus(
  49. azlmbr.bus.Broadcast, "CapturePassTimestamp", f'{self.output_path}/frame{frame_number}_timestamps.json')
  50. if success:
  51. self.wait_until_data()
  52. general.log('Pass timestamps captured.')
  53. else:
  54. general.log('Failed to capture pass timestamps.')
  55. return self.capturedData
  56. def capture_cpu_frame_time(self, frame_number):
  57. """
  58. Capture CPU frame times and block further execution until it has been written to the disk.
  59. """
  60. self.handler = azlmbr.atom.ProfilingCaptureNotificationBusHandler()
  61. self.handler.connect()
  62. self.handler.add_callback('OnCaptureCpuFrameTimeFinished', self.on_data_captured)
  63. self.done = False
  64. self.capturedData = False
  65. success = azlmbr.atom.ProfilingCaptureRequestBus(
  66. azlmbr.bus.Broadcast, "CaptureCpuFrameTime", f'{self.output_path}/cpu_frame{frame_number}_time.json')
  67. if success:
  68. self.wait_until_data()
  69. general.log('CPU frame time captured.')
  70. else:
  71. general.log('Failed to capture CPU frame time.')
  72. return self.capturedData
  73. def on_data_captured(self, parameters):
  74. # the parameters come in as a tuple
  75. if parameters[0]:
  76. general.log('Captured data successfully.')
  77. self.capturedData = True
  78. else:
  79. general.log('Failed to capture data.')
  80. self.done = True
  81. self.handler.disconnect()
  82. def wait_until_data(self):
  83. frames_waited = 0
  84. while self.done == False:
  85. general.idle_wait_frames(1)
  86. if frames_waited > self.max_frames_to_wait:
  87. general.log('Timed out while waiting for the data to be captured')
  88. self.handler.disconnect()
  89. break
  90. else:
  91. frames_waited = frames_waited + 1
  92. general.log(f'(waited {frames_waited} frames)')