39 #include "../../../Primitives/interface/MemoryAllocator.h"
40 #include "../../../Common/interface/STDAllocator.hpp"
41 #include "../../../Platforms/interface/Atomics.hpp"
42 #include "../../../Platforms/Basic/interface/DebugUtilities.hpp"
67 template <typename ResourceType, typename = typename std::enable_if<std::is_object<ResourceType>::value>::type>
72 class SpecificStaleResource final :
public StaleResourceBase
75 SpecificStaleResource(ResourceType&& SpecificResource) :
76 m_SpecificResource(std::move(SpecificResource))
80 SpecificStaleResource (
const SpecificStaleResource&) =
delete;
81 SpecificStaleResource (SpecificStaleResource&&) =
delete;
82 SpecificStaleResource&
operator = (
const SpecificStaleResource&) =
delete;
83 SpecificStaleResource&
operator = (SpecificStaleResource&&) =
delete;
86 virtual void Release()
override final
92 ResourceType m_SpecificResource;
95 class SpecificSharedStaleResource final :
public StaleResourceBase
98 SpecificSharedStaleResource(ResourceType&& SpecificResource,
Atomics::Long NumReferences) :
99 m_SpecificResource(std::move(SpecificResource))
101 m_RefCounter = NumReferences;
105 SpecificSharedStaleResource (
const SpecificSharedStaleResource&) =
delete;
106 SpecificSharedStaleResource (SpecificSharedStaleResource&&) =
delete;
107 SpecificSharedStaleResource&
operator = (
const SpecificSharedStaleResource&) =
delete;
108 SpecificSharedStaleResource&
operator = (SpecificSharedStaleResource&&) =
delete;
111 virtual void Release()
override final
120 ResourceType m_SpecificResource;
126 static_cast<StaleResourceBase*
>(
new SpecificStaleResource{std::move(Resource)}) :
127 static_cast<StaleResourceBase*
>(
new SpecificSharedStaleResource{std::move(Resource), NumReferences})};
131 m_pStaleResource(std::move(rhs.m_pStaleResource))
133 rhs.m_pStaleResource =
nullptr;
137 m_pStaleResource{rhs.m_pStaleResource}
148 m_pStaleResource =
nullptr;
153 if (m_pStaleResource !=
nullptr)
154 m_pStaleResource->Release();
158 class StaleResourceBase
161 virtual ~StaleResourceBase() = 0;
162 virtual void Release() = 0;
166 m_pStaleResource(pStaleResource)
169 StaleResourceBase* m_pStaleResource;
172 inline DynamicStaleResourceWrapper::StaleResourceBase::~StaleResourceBase()
177 template <
typename ResourceType>
183 VERIFY(NumReferences == 1,
"Number of references must be 1 for StaticStaleResourceWrapper");
188 m_StaleResource(std::move(rhs.m_StaleResource))
193 m_StaleResource = std::move(rhs.m_StaleResource);
204 m_StaleResource{std::move(StaleResource)}
207 ResourceType m_StaleResource;
220 template <
typename ResourceWrapperType>
226 m_ReleaseQueue (
STD_ALLOCATOR_RAW_MEM(ReleaseQueueElemType, Allocator,
"Allocator for deque<ReleaseQueueElemType>")),
227 m_StaleResources(
STD_ALLOCATOR_RAW_MEM(ReleaseQueueElemType, Allocator,
"Allocator for deque<ReleaseQueueElemType>"))
233 DEV_CHECK_ERR(m_StaleResources.empty(),
"Not all stale objects were destroyed");
234 DEV_CHECK_ERR(m_ReleaseQueue.empty(),
"Release queue is not empty");
240 template <typename ResourceType, typename = typename std::enable_if<std::is_object<ResourceType>::value>::type>
243 return ResourceWrapperType::Create(std::move(Resource), NumReferences);
249 template <typename ResourceType, typename = typename std::enable_if<std::is_object<ResourceType>::value>::type>
260 std::lock_guard<std::mutex> LockGuard(m_StaleObjectsMutex);
261 m_StaleResources.emplace_back(NextCommandListNumber, std::move(Wrapper));
269 std::lock_guard<std::mutex> LockGuard(m_StaleObjectsMutex);
270 m_StaleResources.emplace_back(NextCommandListNumber, Wrapper);
276 template <typename ResourceType, typename = typename std::enable_if<std::is_object<ResourceType>::value>::type>
287 std::lock_guard<std::mutex> ReleaseQueueLock(m_ReleaseQueueMutex);
288 m_ReleaseQueue.emplace_back(FenceValue, std::move(Wrapper));
296 std::lock_guard<std::mutex> ReleaseQueueLock(m_ReleaseQueueMutex);
297 m_ReleaseQueue.emplace_back(FenceValue, Wrapper);
303 template <
typename ResourceType,
typename IteratorType>
306 std::lock_guard<std::mutex> ReleaseQueueLock(m_ReleaseQueueMutex);
307 ResourceType Resource;
308 while (Iterator(Resource))
310 m_ReleaseQueue.emplace_back(FenceValue,
CreateWrapper(std::move(Resource), 1));
325 std::lock_guard<std::mutex> StaleObjectsLock(m_StaleObjectsMutex);
326 std::lock_guard<std::mutex> ReleaseQueueLock(m_ReleaseQueueMutex);
327 while (!m_StaleResources.empty())
329 auto& FirstStaleObj = m_StaleResources.front();
330 if (FirstStaleObj.first <= SubmittedCmdBuffNumber)
332 m_ReleaseQueue.emplace_back(FenceValue, std::move(FirstStaleObj.second));
333 m_StaleResources.pop_front();
346 std::lock_guard<std::mutex> LockGuard(m_ReleaseQueueMutex);
350 while (!m_ReleaseQueue.empty())
352 auto& FirstObj = m_ReleaseQueue.front();
353 if (FirstObj.first <= CompletedFenceValue)
354 m_ReleaseQueue.pop_front();
363 return m_StaleResources.size();
369 return m_ReleaseQueue.size();
373 std::mutex m_ReleaseQueueMutex;
374 using ReleaseQueueElemType = std::pair<Uint64, ResourceWrapperType>;
375 std::deque<ReleaseQueueElemType, STDAllocatorRawMem<ReleaseQueueElemType>> m_ReleaseQueue;
377 std::mutex m_StaleObjectsMutex;
378 std::deque<ReleaseQueueElemType, STDAllocatorRawMem<ReleaseQueueElemType>> m_StaleResources;