3434#include < thread>
3535#include < vector>
3636#include < unordered_set>
37+ #include < mutex>
3738
3839#include " RenderDevice.h"
3940#include " DeviceObjectBase.hpp"
@@ -308,13 +309,6 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
308309 m_wpImmediateContexts[Ctx] = pImmediateContext;
309310 }
310311
311- // / Set weak reference to the deferred context
312- void SetDeferredContext (size_t Ctx, DeviceContextImplType* pDeferredCtx)
313- {
314- VERIFY (m_wpDeferredContexts[Ctx].Lock () == nullptr , " Deferred context has already been set" );
315- m_wpDeferredContexts[Ctx] = pDeferredCtx;
316- }
317-
318312 // / Returns the number of immediate contexts
319313 size_t GetNumImmediateContexts () const
320314 {
@@ -324,11 +318,23 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
324318 // / Returns number of deferred contexts
325319 size_t GetNumDeferredContexts () const
326320 {
321+ std::lock_guard<std::mutex> Guard{m_DeferredCtxMtx};
327322 return m_wpDeferredContexts.size ();
328323 }
329324
330- RefCntAutoPtr<DeviceContextImplType> GetImmediateContext (size_t Ctx) { return m_wpImmediateContexts[Ctx].Lock (); }
331- RefCntAutoPtr<DeviceContextImplType> GetDeferredContext (size_t Ctx) { return m_wpDeferredContexts[Ctx].Lock (); }
325+ RefCntAutoPtr<DeviceContextImplType> GetImmediateContext (size_t Ctx)
326+ {
327+ return Ctx < m_wpImmediateContexts.size () ?
328+ m_wpImmediateContexts[Ctx].Lock () :
329+ RefCntAutoPtr<DeviceContextImplType>{};
330+ }
331+ RefCntAutoPtr<DeviceContextImplType> GetDeferredContext (size_t Ctx)
332+ {
333+ std::lock_guard<std::mutex> Guard{m_DeferredCtxMtx};
334+ return Ctx < m_wpDeferredContexts.size () ?
335+ m_wpDeferredContexts[Ctx].Lock () :
336+ RefCntAutoPtr<DeviceContextImplType>{};
337+ }
332338
333339 FixedBlockMemoryAllocator& GetTexViewObjAllocator () { return m_TexViewObjAllocator; }
334340 FixedBlockMemoryAllocator& GetBuffViewObjAllocator () { return m_BuffViewObjAllocator; }
@@ -454,11 +460,11 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
454460 const std::string ObjectDescString = GetObjectDescString (Desc);
455461 if (!ObjectDescString.empty ())
456462 {
457- LOG_ERROR (" Failed to create " , ObjectTypeName, " object '" , (Desc.Name ? Desc.Name : " " ), " '\n " , ObjectDescString);
463+ LOG_ERROR (" Failed to create " , ObjectTypeName, " '" , (Desc.Name ? Desc.Name : " " ), " '\n " , ObjectDescString);
458464 }
459465 else
460466 {
461- LOG_ERROR (" Failed to create " , ObjectTypeName, " object '" , (Desc.Name ? Desc.Name : " " ), " '" );
467+ LOG_ERROR (" Failed to create " , ObjectTypeName, " '" , (Desc.Name ? Desc.Name : " " ), " '" );
462468 }
463469 }
464470 }
@@ -549,7 +555,7 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
549555 template <typename ... ExtraArgsType>
550556 void CreateRenderPassImpl (IRenderPass** ppRenderPass, const RenderPassDesc& Desc, const ExtraArgsType&... ExtraArgs)
551557 {
552- CreateDeviceObject (" RenderPass " , Desc, ppRenderPass,
558+ CreateDeviceObject (" Render Pass " , Desc, ppRenderPass,
553559 [&]() //
554560 {
555561 RenderPassImplType* pRenderPassImpl = NEW_RC_OBJ (m_RenderPassAllocator, " Render instance" , RenderPassImplType)(static_cast <RenderDeviceImplType*>(this ), Desc, ExtraArgs...);
@@ -571,7 +577,7 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
571577 template <typename ... ExtraArgsType>
572578 void CreateBLASImpl (IBottomLevelAS** ppBLAS, const BottomLevelASDesc& Desc, const ExtraArgsType&... ExtraArgs)
573579 {
574- CreateDeviceObject (" BottomLevelAS " , Desc, ppBLAS,
580+ CreateDeviceObject (" Bottom-level AS " , Desc, ppBLAS,
575581 [&]() //
576582 {
577583 BottomLevelASImplType* pBottomLevelASImpl = NEW_RC_OBJ (m_BLASAllocator, " BottomLevelAS instance" , BottomLevelASImplType)(static_cast <RenderDeviceImplType*>(this ), Desc, ExtraArgs...);
@@ -582,7 +588,7 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
582588 template <typename ... ExtraArgsType>
583589 void CreateTLASImpl (ITopLevelAS** ppTLAS, const TopLevelASDesc& Desc, const ExtraArgsType&... ExtraArgs)
584590 {
585- CreateDeviceObject (" TopLevelAS " , Desc, ppTLAS,
591+ CreateDeviceObject (" Top-level AS " , Desc, ppTLAS,
586592 [&]() //
587593 {
588594 TopLevelASImplType* pTopLevelASImpl = NEW_RC_OBJ (m_TLASAllocator, " TopLevelAS instance" , TopLevelASImplType)(static_cast <RenderDeviceImplType*>(this ), Desc, ExtraArgs...);
@@ -592,7 +598,7 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
592598
593599 void CreateSBTImpl (IShaderBindingTable** ppSBT, const ShaderBindingTableDesc& Desc)
594600 {
595- CreateDeviceObject (" ShaderBindingTable " , Desc, ppSBT,
601+ CreateDeviceObject (" Shader Binding Table " , Desc, ppSBT,
596602 [&]() //
597603 {
598604 ShaderBindingTableImplType* pSBTImpl = NEW_RC_OBJ (m_SBTAllocator, " ShaderBindingTable instance" , ShaderBindingTableImplType)(static_cast <RenderDeviceImplType*>(this ), Desc);
@@ -603,7 +609,7 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
603609 template <typename ... ExtraArgsType>
604610 void CreatePipelineResourceSignatureImpl (IPipelineResourceSignature** ppSignature, const PipelineResourceSignatureDesc& Desc, const ExtraArgsType&... ExtraArgs)
605611 {
606- CreateDeviceObject (" PipelineResourceSignature " , Desc, ppSignature,
612+ CreateDeviceObject (" Pipeline Resource Signature " , Desc, ppSignature,
607613 [&]() //
608614 {
609615 PipelineResourceSignatureImplType* pPRSImpl = NEW_RC_OBJ (m_PipeResSignAllocator, " PipelineResourceSignature instance" , PipelineResourceSignatureImplType)(static_cast <RenderDeviceImplType*>(this ), Desc, ExtraArgs...);
@@ -614,7 +620,7 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
614620 template <typename ... ExtraArgsType>
615621 void CreateDeviceMemoryImpl (IDeviceMemory** ppMemory, const DeviceMemoryCreateInfo& MemCI, const ExtraArgsType&... ExtraArgs)
616622 {
617- CreateDeviceObject (" DeviceMemory " , MemCI.Desc , ppMemory,
623+ CreateDeviceObject (" Device Memory " , MemCI.Desc , ppMemory,
618624 [&]() //
619625 {
620626 DeviceMemoryImplType* pDevMemImpl = NEW_RC_OBJ (m_MemObjAllocator, " DeviceMemory instance" , DeviceMemoryImplType)(static_cast <RenderDeviceImplType*>(this ), MemCI, ExtraArgs...);
@@ -624,14 +630,54 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
624630
625631 void CreatePipelineStateCacheImpl (IPipelineStateCache** ppCache, const PipelineStateCacheCreateInfo& PSOCacheCI)
626632 {
627- CreateDeviceObject (" PSOCache " , PSOCacheCI.Desc , ppCache,
633+ CreateDeviceObject (" PSO Cache " , PSOCacheCI.Desc , ppCache,
628634 [&]() //
629635 {
630636 PipelineStateCacheImplType* pPSOCacheImpl = NEW_RC_OBJ (m_PSOCacheAllocator, " PSOCache instance" , PipelineStateCacheImplType)(static_cast <RenderDeviceImplType*>(this ), PSOCacheCI);
631637 pPSOCacheImpl->QueryInterface (IID_PipelineStateCache, reinterpret_cast <IObject**>(ppCache));
632638 });
633639 }
634640
641+ template <typename ... ExtraArgsType>
642+ void CreateDeferredContextImpl (IDeviceContext** ppContext, const ExtraArgsType&... ExtraArgs)
643+ {
644+ std::lock_guard<std::mutex> Guard{m_DeferredCtxMtx};
645+
646+ Uint32 CtxIndex = 0 ;
647+ while (CtxIndex < m_wpDeferredContexts.size () && m_wpDeferredContexts[CtxIndex].IsValid ())
648+ ++CtxIndex;
649+
650+ const Uint32 ContextId = static_cast <Uint32>(GetNumImmediateContexts ()) + CtxIndex;
651+ const std::string CtxName = std::string{" Deferred context " } + std::to_string (CtxIndex) + " (ContextId: " + std::to_string (ContextId) + " )" ;
652+ DeviceContextDesc Desc{
653+ CtxName.c_str (),
654+ COMMAND_QUEUE_TYPE_UNKNOWN,
655+ true , // IsDeferred
656+ ContextId,
657+ };
658+
659+ CreateDeviceObject (" Device context" , Desc, ppContext,
660+ [&]() //
661+ {
662+ DeviceContextImplType* pCtxImpl = NEW_RC_OBJ (GetRawAllocator (), " DeviceContext instance" , DeviceContextImplType)(
663+ static_cast <RenderDeviceImplType*>(this ),
664+ Desc,
665+ ExtraArgs...);
666+ pCtxImpl->QueryInterface (IID_DeviceContext, reinterpret_cast <IObject**>(ppContext));
667+ });
668+
669+ if (*ppContext != nullptr )
670+ {
671+ if (CtxIndex >= m_wpDeferredContexts.size ())
672+ {
673+ VERIFY_EXPR (CtxIndex == m_wpDeferredContexts.size ());
674+ m_wpDeferredContexts.resize (CtxIndex + 1 );
675+ }
676+
677+ m_wpDeferredContexts[CtxIndex] = static_cast <DeviceContextImplType*>(*ppContext);
678+ }
679+ }
680+
635681protected:
636682 RefCntAutoPtr<IEngineFactory> m_pEngineFactory;
637683
@@ -651,6 +697,7 @@ class RenderDeviceBase : public ObjectBase<typename EngineImplTraits::RenderDevi
651697 std::vector<RefCntWeakPtr<DeviceContextImplType>, STDAllocatorRawMem<RefCntWeakPtr<DeviceContextImplType>>> m_wpImmediateContexts;
652698
653699 // / Weak references to deferred contexts.
700+ mutable std::mutex m_DeferredCtxMtx;
654701 std::vector<RefCntWeakPtr<DeviceContextImplType>, STDAllocatorRawMem<RefCntWeakPtr<DeviceContextImplType>>> m_wpDeferredContexts;
655702
656703 IMemoryAllocator& m_RawMemAllocator; // /< Raw memory allocator
0 commit comments