BsVulkanOcclusionQuery.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsVulkanOcclusionQuery.h"
  4. #include "BsVulkanDevice.h"
  5. #include "BsVulkanQueryManager.h"
  6. #include "BsVulkanRenderAPI.h"
  7. #include "BsVulkanCommandBuffer.h"
  8. #include "BsRenderStats.h"
  9. namespace BansheeEngine
  10. {
  11. VulkanOcclusionQuery::VulkanOcclusionQuery(VulkanDevice& device, bool binary)
  12. : OcclusionQuery(binary), mDevice(device), mQuery(nullptr), mNumSamples(0), mQueryEndCalled(false)
  13. , mQueryFinalized(false)
  14. {
  15. BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
  16. }
  17. VulkanOcclusionQuery::~VulkanOcclusionQuery()
  18. {
  19. if (mQuery != nullptr)
  20. mDevice.getQueryPool().releaseQuery(mQuery);
  21. BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
  22. }
  23. void VulkanOcclusionQuery::begin(const SPtr<CommandBuffer>& cb)
  24. {
  25. VulkanQueryPool& queryPool = mDevice.getQueryPool();
  26. // Clear any existing query
  27. if (mQuery != nullptr)
  28. {
  29. queryPool.releaseQuery(mQuery);
  30. mQuery = nullptr;
  31. }
  32. mQueryEndCalled = false;
  33. mNumSamples = 0;
  34. // Retrieve and queue new query
  35. VulkanCommandBuffer* vulkanCB;
  36. if (cb != nullptr)
  37. vulkanCB = static_cast<VulkanCommandBuffer*>(cb.get());
  38. else
  39. vulkanCB = static_cast<VulkanCommandBuffer*>(gVulkanRenderAPI()._getMainCommandBuffer());
  40. VulkanCmdBuffer* internalCB = vulkanCB->getInternal();
  41. mQuery = queryPool.beginOcclusionQuery(internalCB, !mBinary);
  42. setActive(true);
  43. }
  44. void VulkanOcclusionQuery::end(const SPtr<CommandBuffer>& cb)
  45. {
  46. if(mQuery == nullptr)
  47. {
  48. LOGERR("end() called but query was never started.");
  49. return;
  50. }
  51. mQueryEndCalled = true;
  52. mQueryFinalized = false;
  53. VulkanCommandBuffer* vulkanCB;
  54. if (cb != nullptr)
  55. vulkanCB = static_cast<VulkanCommandBuffer*>(cb.get());
  56. else
  57. vulkanCB = static_cast<VulkanCommandBuffer*>(gVulkanRenderAPI()._getMainCommandBuffer());
  58. VulkanQueryPool& queryPool = mDevice.getQueryPool();
  59. VulkanCmdBuffer* internalCB = vulkanCB->getInternal();
  60. queryPool.endOcclusionQuery(mQuery, internalCB);
  61. }
  62. bool VulkanOcclusionQuery::isReady() const
  63. {
  64. if (!mQueryEndCalled)
  65. return false;
  66. if (mQueryFinalized)
  67. return true;
  68. UINT64 numSamples;
  69. return !mQuery->isBound() && mQuery->getResult(numSamples);
  70. }
  71. UINT32 VulkanOcclusionQuery::getNumSamples()
  72. {
  73. if(!mQueryFinalized)
  74. {
  75. UINT64 numSamples;
  76. if(!mQuery->isBound() && mQuery->getResult(numSamples))
  77. {
  78. mQueryFinalized = true;
  79. mNumSamples = numSamples;
  80. VulkanQueryPool& queryPool = mDevice.getQueryPool();
  81. queryPool.releaseQuery(mQuery);
  82. mQuery = nullptr;
  83. }
  84. }
  85. return (UINT32)mNumSamples;
  86. }
  87. }