3
0

GpuQuerySystem.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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 <Atom/RHI/CommandList.h>
  9. #include <Atom/RHI/Factory.h>
  10. #include <Atom/RHI/FrameGraphInterface.h>
  11. #include <Atom/RHI/RHISystemInterface.h>
  12. #include <Atom/RPI.Public/GpuQuery/GpuQuerySystem.h>
  13. #include <Atom/RPI.Public/GpuQuery/TimestampQueryPool.h>
  14. #include <Atom/RPI.Reflect/GpuQuerySystemDescriptor.h>
  15. #include <AzCore/Interface/Interface.h>
  16. namespace AZ
  17. {
  18. namespace RPI
  19. {
  20. GpuQuerySystemInterface* GpuQuerySystemInterface::Get()
  21. {
  22. return Interface<GpuQuerySystemInterface>::Get();
  23. }
  24. void GpuQuerySystem::Init(const GpuQuerySystemDescriptor& desc)
  25. {
  26. // Cache the feature support for QueryTypes.
  27. CacheFeatureSupport();
  28. // Create the Timestamp QueryPool.
  29. if (IsQueryTypeSupported(RHI::QueryType::Timestamp))
  30. {
  31. // The limit of RPI Queries that is able to be created with this pool.
  32. const uint32_t TimestampQueryCount = desc.m_timestampQueryCount;
  33. // Create the Timestamp QueryPool.
  34. QueryPoolPtr timestampQueryPool = TimestampQueryPool::CreateTimestampQueryPool(TimestampQueryCount);
  35. m_queryPoolArray[static_cast<uint32_t>(RHI::QueryType::Timestamp)] = AZStd::move(timestampQueryPool);
  36. }
  37. // Create the Pipeline Statistics QueryPool.
  38. if (IsQueryTypeSupported(RHI::QueryType::PipelineStatistics))
  39. {
  40. // The limit of RPI Queries that is able to be created with this pool.
  41. const uint32_t PipelineStatisticsQueryCount = desc.m_statisticsQueryCount;
  42. // The amount of RHI Queries required to calculate a single result.
  43. const uint32_t RhiQueriesPerPipelineStatisticsResult = 1u;
  44. // Create the PipelineStatistics QueryPool.
  45. QueryPoolPtr pipelineStatisticsQueryPool = QueryPool::CreateQueryPool(PipelineStatisticsQueryCount, RhiQueriesPerPipelineStatisticsResult, RHI::QueryType::PipelineStatistics, desc.m_statisticsQueryFlags);
  46. m_queryPoolArray[static_cast<uint32_t>(RHI::QueryType::PipelineStatistics)] = AZStd::move(pipelineStatisticsQueryPool);
  47. }
  48. // Register the system to the interface.
  49. Interface<GpuQuerySystemInterface>::Register(this);
  50. }
  51. void GpuQuerySystem::Shutdown()
  52. {
  53. // Ensure all the query related resource are released before RHI System is shutdown.
  54. for (auto& queryPool : m_queryPoolArray)
  55. {
  56. queryPool = nullptr;
  57. }
  58. // Unregister the system to the interface.
  59. Interface<GpuQuerySystemInterface>::Unregister(this);
  60. }
  61. void GpuQuerySystem::Update()
  62. {
  63. AZ_PROFILE_SCOPE(RPI, "GpuQuerySystem: Update");
  64. for (auto& queryPool : m_queryPoolArray)
  65. {
  66. if (queryPool)
  67. {
  68. queryPool->Update();
  69. }
  70. }
  71. }
  72. RHI::Ptr<Query> GpuQuerySystem::CreateQuery(RHI::QueryType queryType, RHI::QueryPoolScopeAttachmentType attachmentType, RHI::ScopeAttachmentAccess attachmentAccess)
  73. {
  74. RPI::QueryPool* queryPool = GetQueryPoolByType(queryType);
  75. if (queryPool)
  76. {
  77. return queryPool->CreateQuery(attachmentType, attachmentAccess);
  78. }
  79. return nullptr;
  80. }
  81. void GpuQuerySystem::CacheFeatureSupport()
  82. {
  83. // Use the device that is registered with the RHISystemInterface
  84. RHI::Device* device = RHI::RHISystemInterface::Get()->GetDevice();
  85. for (RHI::QueryTypeFlags commandQueueQueryTypeFlags : device->GetFeatures().m_queryTypesMask)
  86. {
  87. m_queryTypeSupport |= commandQueueQueryTypeFlags;
  88. }
  89. }
  90. bool GpuQuerySystem::IsQueryTypeValid(RHI::QueryType queryType)
  91. {
  92. const uint32_t queryTypeIndex = static_cast<uint32_t>(queryType);
  93. return queryTypeIndex < static_cast<uint32_t>(RHI::QueryType::Count);
  94. }
  95. bool GpuQuerySystem::IsQueryTypeSupported(RHI::QueryType queryType)
  96. {
  97. AZ_Assert(IsQueryTypeValid(queryType), "Provided QueryType is invalid");
  98. return static_cast<uint32_t>(m_queryTypeSupport) & AZ_BIT(static_cast<uint32_t>(queryType));
  99. }
  100. RPI::QueryPool* GpuQuerySystem::GetQueryPoolByType(RHI::QueryType queryType)
  101. {
  102. const uint32_t queryTypeIndex = static_cast<uint32_t>(queryType);
  103. const bool validQueryType = IsQueryTypeValid(queryType);
  104. // Only return the QueryPool if the QueryType is valid and if the QueryPool is initialized
  105. if (validQueryType && m_queryPoolArray[queryTypeIndex])
  106. {
  107. return m_queryPoolArray[queryTypeIndex].get();
  108. }
  109. return nullptr;
  110. }
  111. }; // namespace RPI
  112. }; // namespace AZ