| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "BsVulkanResource.h"
- #include "BsVulkanCommandBuffer.h"
- #include "CoreThread/BsCoreThread.h"
- namespace bs { namespace ct
- {
- VulkanResource::VulkanResource(VulkanResourceManager* owner, bool concurrency)
- {
- Lock lock(mMutex);
- mOwner = owner;
- mQueueFamily = -1;
- mState = concurrency ? State::Shared : State::Normal;
- mNumUsedHandles = 0;
- mNumBoundHandles = 0;
- bs_zero_out(mReadUses);
- bs_zero_out(mWriteUses);
- }
- VulkanResource::~VulkanResource()
- {
- THROW_IF_NOT_CORE_THREAD
- Lock lock(mMutex);
- assert(mState == State::Destroyed && "Vulkan resource getting destructed without destroy() called first.");
- }
- void VulkanResource::notifyBound()
- {
- Lock lock(mMutex);
- assert(mState != State::Destroyed);
- mNumBoundHandles++;
- }
- void VulkanResource::notifyUsed(UINT32 globalQueueIdx, UINT32 queueFamily, VulkanUseFlags useFlags)
- {
- Lock lock(mMutex);
- assert(useFlags != VulkanUseFlag::None);
- bool isUsed = mNumUsedHandles > 0;
- if(isUsed && mState == State::Normal) // Used without support for concurrency
- {
- assert(mQueueFamily == queueFamily &&
- "Vulkan resource without concurrency support can only be used by one queue family at once.");
- }
- mNumUsedHandles++;
- mQueueFamily = queueFamily;
- assert(globalQueueIdx < MAX_UNIQUE_QUEUES);
-
- if (useFlags.isSet(VulkanUseFlag::Read))
- {
- assert(mReadUses[globalQueueIdx] < 255 && "Resource used in too many command buffers at once.");
- mReadUses[globalQueueIdx]++;
- }
-
- if(useFlags.isSet(VulkanUseFlag::Write))
- {
- assert(mWriteUses[globalQueueIdx] < 255 && "Resource used in too many command buffers at once.");
- mWriteUses[globalQueueIdx]++;
- }
- }
- void VulkanResource::notifyDone(UINT32 globalQueueIdx, VulkanUseFlags useFlags)
- {
- bool destroy;
- {
- Lock lock(mMutex);
- mNumUsedHandles--;
- mNumBoundHandles--;
- if (useFlags.isSet(VulkanUseFlag::Read))
- {
- assert(mReadUses[globalQueueIdx] > 0);
- mReadUses[globalQueueIdx]--;
- }
- if (useFlags.isSet(VulkanUseFlag::Write))
- {
- assert(mWriteUses[globalQueueIdx] > 0);
- mWriteUses[globalQueueIdx]--;
- }
- bool isBound = mNumBoundHandles > 0;
- destroy = !isBound && mState == State::Destroyed; // Queued for destruction
- }
- // (Safe to check outside of mutex as we guarantee that once queued for destruction, state cannot be changed)
- if (destroy)
- mOwner->destroy(this);
- }
- void VulkanResource::notifyUnbound()
- {
- bool destroy;
- {
- Lock lock(mMutex);
- mNumBoundHandles--;
- bool isBound = mNumBoundHandles > 0;
- destroy = !isBound && mState == State::Destroyed; // Queued for destruction
- }
- // (Safe to check outside of mutex as we guarantee that once queued for destruction, state cannot be changed)
- if (destroy)
- mOwner->destroy(this);
- }
- UINT32 VulkanResource::getUseInfo(VulkanUseFlags useFlags) const
- {
- UINT32 mask = 0;
- if(useFlags.isSet(VulkanUseFlag::Read))
- {
- for (UINT32 i = 0; i < MAX_UNIQUE_QUEUES; i++)
- {
- if (mReadUses[i] > 0)
- mask |= 1 << i;
- }
- }
- if (useFlags.isSet(VulkanUseFlag::Write))
- {
- for (UINT32 i = 0; i < MAX_UNIQUE_QUEUES; i++)
- {
- if (mWriteUses[i] > 0)
- mask |= 1 << i;
- }
- }
- return mask;
- }
- void VulkanResource::destroy()
- {
- bool destroy;
- {
- Lock lock(mMutex);
- assert(mState != State::Destroyed && "Vulkan resource destroy() called more than once.");
- mState = State::Destroyed;
- // If not bound anyhwere, destroy right away, otherwise check when it is reported as finished on the device
- bool isBound = mNumBoundHandles > 0;
- destroy = !isBound;
- }
- // (Safe to check outside of mutex as we guarantee that once queued for destruction, state cannot be changed)
- if (destroy)
- mOwner->destroy(this);
- }
- VulkanResourceManager::VulkanResourceManager(VulkanDevice& device)
- :mDevice(device)
- { }
- VulkanResourceManager::~VulkanResourceManager()
- {
- #if BS_DEBUG_MODE
- Lock lock(mMutex);
- assert(mResources.empty() && "Resource manager shutting down but not all resources were released.");
- #endif
- }
- void VulkanResourceManager::destroy(VulkanResource* resource)
- {
- #if BS_DEBUG_MODE
- {
- Lock lock(mMutex);
- mResources.erase(resource);
- }
- #endif
- bs_delete(resource);
- }
- }}
|