BsVulkanQueryManager.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsVulkanPrerequisites.h"
  5. #include "BsVulkanResource.h"
  6. #include "Managers/BsQueryManager.h"
  7. namespace bs { namespace ct
  8. {
  9. /** @addtogroup Vulkan
  10. * @{
  11. */
  12. /**
  13. * Pool that allocates and distributes Vulkan queries.
  14. *
  15. * @note Thread safe.
  16. */
  17. class VulkanQueryPool
  18. {
  19. public:
  20. VulkanQueryPool(VulkanDevice& device);
  21. ~VulkanQueryPool();
  22. /**
  23. * Begins a timer query on the provided command buffer.
  24. *
  25. * @param[in] cb Command buffer to begin the query on.
  26. * @return Relevant query object that was queued. It must be released via releaseQuery() once the
  27. * caller is done accessing it.
  28. */
  29. VulkanQuery* beginTimerQuery(VulkanCmdBuffer* cb);
  30. /**
  31. * Begins an occlusion query on the provided command buffer. Must be followed with a call to endOcclusionQuery
  32. * on the same command buffer, before the command buffer gets submitted.
  33. *
  34. * @param[in] cb Command buffer to begin the query on.
  35. * @param[in] precise When true the query will be able to return the precise number of processed samples,
  36. * otherwise it just returns a boolean value if anything was drawn.
  37. * @return Relevant query object that was queued. It must be released via releaseQuery() once the
  38. * caller is done accessing it.
  39. */
  40. VulkanQuery* beginOcclusionQuery(VulkanCmdBuffer* cb, bool precise);
  41. /**
  42. * End am occlusion query query on the provided command buffer.
  43. *
  44. * @param[in] query Query previously begun with beginOcclusionQuery().
  45. * @param[in] cb Command buffer to end the query on.
  46. */
  47. void endOcclusionQuery(VulkanQuery* query, VulkanCmdBuffer* cb);
  48. /** Releases a previously retrieved query, ensuring it can be re-used. */
  49. void releaseQuery(VulkanQuery* query);
  50. private:
  51. /** Query buffer pool and related information. */
  52. struct PoolInfo
  53. {
  54. VkQueryPool pool = VK_NULL_HANDLE;
  55. UINT32 startIdx;
  56. };
  57. /** Attempts to find a free query of the specified type, or allocates a new one. Creates new pools as needed. */
  58. VulkanQuery* getQuery(VkQueryType type);
  59. /** Creates a new Vulkan query pool object. */
  60. PoolInfo& allocatePool(VkQueryType type);
  61. static const UINT32 NUM_QUERIES_PER_POOL = 16;
  62. VulkanDevice& mDevice;
  63. Vector<VulkanQuery*> mTimerQueries;
  64. Vector<VulkanQuery*> mOcclusionQueries;
  65. Vector<PoolInfo> mTimerPools;
  66. Vector<PoolInfo> mOcclusionPools;
  67. Mutex mMutex;
  68. };
  69. /** Handles creation of Vulkan queries. */
  70. class VulkanQueryManager : public QueryManager
  71. {
  72. public:
  73. VulkanQueryManager(VulkanRenderAPI& rapi);
  74. ~VulkanQueryManager();
  75. /** @copydoc QueryManager::createEventQuery */
  76. SPtr<EventQuery> createEventQuery(UINT32 deviceIdx = 0) const override;
  77. /** @copydoc QueryManager::createTimerQuery */
  78. SPtr<TimerQuery> createTimerQuery(UINT32 deviceIdx = 0) const override;
  79. /** @copydoc QueryManager::createOcclusionQuery */
  80. SPtr<OcclusionQuery> createOcclusionQuery(bool binary, UINT32 deviceIdx = 0) const override;
  81. private:
  82. VulkanRenderAPI& mRenderAPI;
  83. };
  84. /** Wrapper around a single query in a Vulkan query pool object. */
  85. class VulkanQuery : public VulkanResource
  86. {
  87. public:
  88. VulkanQuery(VulkanResourceManager* owner, VkQueryPool pool, UINT32 queryIdx);
  89. /**
  90. * Attempts to retrieve the result from the query. The result is only valid if the query stopped executing on the
  91. * GPU (otherwise previous query results could be accessed, if the reset command hasn't executed yet).
  92. *
  93. * @param[out] result Value of the query, if the method return true. Undefined otherwise.
  94. * @return True if the result is ready, false otherwise.
  95. */
  96. bool getResult(UINT64& result) const;
  97. /** Queues a command for the query reset, on the provided command buffer. */
  98. void reset(VkCommandBuffer cmdBuf);
  99. private:
  100. friend class VulkanQueryPool;
  101. VkQueryPool mPool;
  102. UINT32 mQueryIdx;
  103. bool mFree;
  104. bool mNeedsReset;
  105. };
  106. /** @} */
  107. }}