BsVulkanTimerQuery.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsVulkanTimerQuery.h"
  4. #include "BsVulkanDevice.h"
  5. #include "BsVulkanQueryManager.h"
  6. #include "BsVulkanRenderAPI.h"
  7. #include "BsVulkanCommandBuffer.h"
  8. #include "BsRenderStats.h"
  9. namespace bs { namespace ct
  10. {
  11. VulkanTimerQuery::VulkanTimerQuery(VulkanDevice& device)
  12. : mDevice(device), mBeginQuery(nullptr), mEndQuery(nullptr), mTimeDelta(0.0f), mQueryEndCalled(false)
  13. , mQueryFinalized(false)
  14. {
  15. BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
  16. }
  17. VulkanTimerQuery::~VulkanTimerQuery()
  18. {
  19. if (mBeginQuery != nullptr)
  20. mDevice.getQueryPool().releaseQuery(mBeginQuery);
  21. if (mEndQuery != nullptr)
  22. mDevice.getQueryPool().releaseQuery(mEndQuery);
  23. BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
  24. }
  25. void VulkanTimerQuery::begin(const SPtr<CommandBuffer>& cb)
  26. {
  27. VulkanQueryPool& queryPool = mDevice.getQueryPool();
  28. // Clear any existing queries
  29. if (mBeginQuery != nullptr)
  30. {
  31. queryPool.releaseQuery(mBeginQuery);
  32. mBeginQuery = nullptr;
  33. }
  34. if (mEndQuery != nullptr)
  35. {
  36. queryPool.releaseQuery(mEndQuery);
  37. mEndQuery = nullptr;
  38. }
  39. mQueryEndCalled = false;
  40. mTimeDelta = 0.0f;
  41. // Retrieve and queue new query
  42. VulkanCommandBuffer* vulkanCB;
  43. if (cb != nullptr)
  44. vulkanCB = static_cast<VulkanCommandBuffer*>(cb.get());
  45. else
  46. vulkanCB = static_cast<VulkanCommandBuffer*>(gVulkanRenderAPI()._getMainCommandBuffer());
  47. VulkanCmdBuffer* internalCB = vulkanCB->getInternal();
  48. mBeginQuery = queryPool.beginTimerQuery(internalCB);
  49. setActive(true);
  50. }
  51. void VulkanTimerQuery::end(const SPtr<CommandBuffer>& cb)
  52. {
  53. if (mBeginQuery == nullptr)
  54. {
  55. LOGERR("end() called but query was never started.");
  56. return;
  57. }
  58. mQueryEndCalled = true;
  59. mQueryFinalized = false;
  60. VulkanCommandBuffer* vulkanCB;
  61. if (cb != nullptr)
  62. vulkanCB = static_cast<VulkanCommandBuffer*>(cb.get());
  63. else
  64. vulkanCB = static_cast<VulkanCommandBuffer*>(gVulkanRenderAPI()._getMainCommandBuffer());
  65. VulkanQueryPool& queryPool = mDevice.getQueryPool();
  66. VulkanCmdBuffer* internalCB = vulkanCB->getInternal();
  67. mEndQuery = queryPool.beginTimerQuery(internalCB);
  68. }
  69. bool VulkanTimerQuery::isReady() const
  70. {
  71. if (!mQueryEndCalled)
  72. return false;
  73. if (mQueryFinalized)
  74. return true;
  75. UINT64 timeBegin;
  76. bool beginReady = !mBeginQuery->isBound() && mBeginQuery->getResult(timeBegin);
  77. UINT64 timeEnd;
  78. bool endReady = !mEndQuery->isBound() && mEndQuery->getResult(timeEnd);
  79. return beginReady && endReady;
  80. }
  81. float VulkanTimerQuery::getTimeMs()
  82. {
  83. if (!mQueryFinalized)
  84. {
  85. UINT64 timeBegin;
  86. bool beginReady = !mBeginQuery->isBound() && mBeginQuery->getResult(timeBegin);
  87. UINT64 timeEnd;
  88. bool endReady = !mEndQuery->isBound() && mEndQuery->getResult(timeEnd);
  89. if (beginReady && endReady)
  90. {
  91. mQueryFinalized = true;
  92. UINT64 timeDiff = timeEnd - timeBegin;
  93. double timestampToMs = (double)mDevice.getDeviceProperties().limits.timestampPeriod / 1e6; // Nano to milli
  94. mTimeDelta = (float)((double)timeDiff * timestampToMs);
  95. VulkanQueryPool& queryPool = mDevice.getQueryPool();
  96. queryPool.releaseQuery(mBeginQuery);
  97. mBeginQuery = nullptr;
  98. queryPool.releaseQuery(mEndQuery);
  99. mEndQuery = nullptr;
  100. }
  101. }
  102. return mTimeDelta;
  103. }
  104. }}