BsVulkanResource.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsVulkanResource.h"
  4. #include "BsVulkanCommandBuffer.h"
  5. #include "BsCoreThread.h"
  6. namespace BansheeEngine
  7. {
  8. VulkanResource::VulkanResource(VulkanResourceManager* owner, bool concurrency)
  9. {
  10. Lock lock(mMutex);
  11. mOwner = owner;
  12. mQueueFamily = -1;
  13. mState = concurrency ? State::Shared : State::Normal;
  14. mNumUsedHandles = 0;
  15. mNumBoundHandles = 0;
  16. bs_zero_out(mReadUses);
  17. bs_zero_out(mWriteUses);
  18. }
  19. VulkanResource::~VulkanResource()
  20. {
  21. THROW_IF_NOT_CORE_THREAD
  22. Lock lock(mMutex);
  23. assert(mState == State::Destroyed && "Vulkan resource getting destructed without destroy() called first.");
  24. }
  25. void VulkanResource::notifyBound()
  26. {
  27. Lock lock(mMutex);
  28. assert(mState != State::Destroyed);
  29. mNumBoundHandles++;
  30. }
  31. void VulkanResource::notifyUsed(UINT32 globalQueueIdx, UINT32 queueFamily, VulkanUseFlags useFlags)
  32. {
  33. Lock lock(mMutex);
  34. assert(mState != State::Destroyed);
  35. assert(useFlags != VulkanUseFlag::None);
  36. if(isUsed() && mState == State::Normal) // Used without support for concurrency
  37. {
  38. assert(mQueueFamily == queueFamily &&
  39. "Vulkan resource without concurrency support can only be used by one queue family at once.");
  40. }
  41. mNumUsedHandles++;
  42. mQueueFamily = queueFamily;
  43. assert(globalQueueIdx < MAX_UNIQUE_QUEUES);
  44. if (useFlags.isSet(VulkanUseFlag::Read))
  45. {
  46. assert(mReadUses[globalQueueIdx] < 255 && "Resource used in too many command buffers at once.");
  47. mReadUses[globalQueueIdx]++;
  48. }
  49. if(useFlags.isSet(VulkanUseFlag::Write))
  50. {
  51. assert(mWriteUses[globalQueueIdx] < 255 && "Resource used in too many command buffers at once.");
  52. mWriteUses[globalQueueIdx]++;
  53. }
  54. }
  55. void VulkanResource::notifyDone(UINT32 globalQueueIdx, VulkanUseFlags useFlags)
  56. {
  57. Lock lock(mMutex);
  58. mNumUsedHandles--;
  59. mNumBoundHandles--;
  60. if (useFlags.isSet(VulkanUseFlag::Read))
  61. {
  62. assert(mReadUses[globalQueueIdx] > 0);
  63. mReadUses[globalQueueIdx]--;
  64. }
  65. if (useFlags.isSet(VulkanUseFlag::Write))
  66. {
  67. assert(mWriteUses[globalQueueIdx] > 0);
  68. mWriteUses[globalQueueIdx]--;
  69. }
  70. if (!isBound() && mState == State::Destroyed) // Queued for destruction
  71. mOwner->destroy(this);
  72. }
  73. void VulkanResource::notifyUnbound()
  74. {
  75. Lock lock(mMutex);
  76. mNumBoundHandles--;
  77. if (!isBound() && mState == State::Destroyed) // Queued for destruction
  78. mOwner->destroy(this);
  79. }
  80. UINT32 VulkanResource::getUseInfo(VulkanUseFlags& useFlags) const
  81. {
  82. useFlags = VulkanUseFlag::None;
  83. UINT32 mask = 0;
  84. for(UINT32 i = 0; i < MAX_UNIQUE_QUEUES; i++)
  85. {
  86. if (mReadUses[i] > 0)
  87. {
  88. mask |= 1 << i;
  89. useFlags |= VulkanUseFlag::Read;
  90. }
  91. if (mWriteUses[i] > 0)
  92. {
  93. mask |= 1 << i;
  94. useFlags |= VulkanUseFlag::Write;
  95. }
  96. }
  97. return mask;
  98. }
  99. void VulkanResource::destroy()
  100. {
  101. Lock lock(mMutex);
  102. assert(mState != State::Destroyed && "Vulkan resource destroy() called more than once.");
  103. mState = State::Destroyed;
  104. // If not bound anyhwere, destroy right away, otherwise check when it is reported as finished on the device
  105. if (!isBound())
  106. mOwner->destroy(this);
  107. }
  108. VulkanResourceManager::VulkanResourceManager(VulkanDevice& device)
  109. :mDevice(device)
  110. { }
  111. VulkanResourceManager::~VulkanResourceManager()
  112. {
  113. #if BS_DEBUG_MODE
  114. Lock lock(mMutex);
  115. assert(mResources.empty() && "Resource manager shutting down but not all resources were released.");
  116. #endif
  117. }
  118. void VulkanResourceManager::destroy(VulkanResource* resource)
  119. {
  120. #if BS_DEBUG_MODE
  121. Lock lock(mMutex);
  122. mResources.erase(resource);
  123. #endif
  124. bs_delete(resource);
  125. }
  126. }