Skip to content

Commit

Permalink
GLTFResourceManager: added TransitionResourceStates method
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Aug 21, 2023
1 parent fc6ffce commit c734bab
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 12 deletions.
60 changes: 60 additions & 0 deletions AssetLoader/interface/GLTFResourceManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,64 @@ class ResourceManager final : public ObjectBase<IObject>
/// Otherwise, returns the net usage stats for all pools.
VertexPoolUsageStats GetVertexPoolUsageStats(const VertexLayoutKey& Key = VertexLayoutKey{});

/// Parameters of the TransitionResourceStates() method.
struct TransitionResourceStatesInfo
{
/// Vertex buffers transition info.
struct VertexBuffersInfo
{
/// Old state that is passed to the OldState member of the StateTransitionDesc structure.
RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN;

/// New state that is passed to the NewState member of the StateTransitionDesc structure.
///
/// If NewState is RESOURCE_STATE_UNKNOWN, the vertex buffers states will not be changed.
RESOURCE_STATE NewState = RESOURCE_STATE_UNKNOWN;

/// Flags that are passed to the Flags member of the StateTransitionDesc structure.
STATE_TRANSITION_FLAGS Flags = STATE_TRANSITION_FLAG_UPDATE_STATE;
} VertexBuffers;

/// Index buffer transition info.
struct IndexBufferInfo
{
/// Old state that is passed to the OldState member of the StateTransitionDesc structure.
RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN;

/// New state that is passed to the NewState member of the StateTransitionDesc structure.
///
/// If NewState is RESOURCE_STATE_UNKNOWN, the index buffer state will not be changed.
RESOURCE_STATE NewState = RESOURCE_STATE_UNKNOWN;

/// Flags that are passed to the Flags member of the StateTransitionDesc structure.
STATE_TRANSITION_FLAGS Flags = STATE_TRANSITION_FLAG_UPDATE_STATE;
} IndexBuffer;

/// Texture atlases transition info.
struct TextureAtlasesInfo
{
/// Old state that is passed to the OldState member of the StateTransitionDesc structure.
RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN;

/// New state that is passed to the NewState member of the StateTransitionDesc structure.
///
/// If NewState is RESOURCE_STATE_UNKNOWN, the texture atlases states will not be changed.
RESOURCE_STATE NewState = RESOURCE_STATE_UNKNOWN;

/// Flags that are passed to the Flags member of the StateTransitionDesc structure.
STATE_TRANSITION_FLAGS Flags = STATE_TRANSITION_FLAG_UPDATE_STATE;
} TextureAtlases;
};

/// Transitions resource states of all vertex buffers, index buffer and texture atlases.
///
/// \param[in] pDevice - Pointer to the render device.
/// \param[in] pContext - Pointer to the device context.
/// \param[in] Info - Resource state transition info, see Diligent::ResourceManager::TransitionResourceStatesInfo.
///
/// \remarks This function is thread-safe.
void TransitionResourceStates(IRenderDevice* pDevice, IDeviceContext* pContext, const TransitionResourceStatesInfo& Info);

private:
template <typename AllocatorType, typename ObjectType>
friend class Diligent::MakeNewRCObj;
Expand Down Expand Up @@ -262,6 +320,8 @@ class ResourceManager final : public ObjectBase<IObject>
using TexAllocationsHashMapType = std::unordered_map<std::string, RefCntWeakPtr<ITextureAtlasSuballocation>>;
std::mutex m_TexAllocationsMtx;
TexAllocationsHashMapType m_TexAllocations;

std::vector<StateTransitionDesc> m_Barriers;
};

} // namespace GLTF
Expand Down
71 changes: 59 additions & 12 deletions AssetLoader/src/GLTFResourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ RefCntAutoPtr<ITextureAtlasSuballocation> ResourceManager::FindTextureAllocation

if (CacheId != nullptr && *CacheId != 0)
{
std::lock_guard<std::mutex> Lock{m_TexAllocationsMtx};
std::lock_guard<std::mutex> Guard{m_TexAllocationsMtx};

auto it = m_TexAllocations.find(CacheId);
if (it != m_TexAllocations.end())
Expand Down Expand Up @@ -152,7 +152,7 @@ RefCntAutoPtr<ITextureAtlasSuballocation> ResourceManager::AllocateTextureSpace(
{
decltype(m_Atlases)::iterator cache_it; // NB: can't initialize it without locking the mutex
{
std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
std::lock_guard<std::mutex> Guard{m_AtlasesMtx};
cache_it = m_Atlases.find(Fmt);
if (cache_it == m_Atlases.end())
{
Expand Down Expand Up @@ -187,7 +187,7 @@ RefCntAutoPtr<ITextureAtlasSuballocation> ResourceManager::AllocateTextureSpace(

if (CacheId != nullptr && *CacheId != 0)
{
std::lock_guard<std::mutex> Lock{m_TexAllocationsMtx};
std::lock_guard<std::mutex> Guard{m_TexAllocationsMtx};
// Note that the same allocation may potentially be created by more
// than one thread if it has not been found in the cache originally
m_TexAllocations.emplace(CacheId, pAllocation);
Expand Down Expand Up @@ -223,7 +223,7 @@ RefCntAutoPtr<IVertexPoolAllocation> ResourceManager::AllocateVertices(const Ver

decltype(m_VertexPools)::iterator pool_it; // NB: can't initialize it without locking the mutex
{
std::lock_guard<std::mutex> Lock{m_VertexPoolsMtx};
std::lock_guard<std::mutex> Guard{m_VertexPoolsMtx};
pool_it = m_VertexPools.find(LayoutKey);
if (pool_it == m_VertexPools.end())
{
Expand Down Expand Up @@ -281,7 +281,7 @@ Uint32 ResourceManager::GetTextureVersion()
{
Uint32 Version = 0;

std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
std::lock_guard<std::mutex> Guard{m_AtlasesMtx};
for (auto atlas_it : m_Atlases)
Version += atlas_it.second->GetVersion();

Expand All @@ -298,7 +298,7 @@ Uint32 ResourceManager::GetVertexPoolsVersion()
{
Uint32 Version = 0;

std::lock_guard<std::mutex> Lock{m_VertexPoolsMtx};
std::lock_guard<std::mutex> Guard{m_VertexPoolsMtx};
for (auto pool_it : m_VertexPools)
Version += pool_it.second->GetVersion();

Expand All @@ -316,7 +316,7 @@ IVertexPool* ResourceManager::GetVertexPool(const VertexLayoutKey& Key)
{
decltype(m_VertexPools)::iterator pool_it; // NB: can't initialize it without locking the mutex
{
std::lock_guard<std::mutex> Lock{m_VertexPoolsMtx};
std::lock_guard<std::mutex> Guard{m_VertexPoolsMtx};
pool_it = m_VertexPools.find(Key);
if (pool_it == m_VertexPools.end())
return nullptr;
Expand All @@ -329,7 +329,7 @@ ITexture* ResourceManager::GetTexture(TEXTURE_FORMAT Fmt, IRenderDevice* pDevice
{
decltype(m_Atlases)::iterator cache_it; // NB: can't initialize it without locking the mutex
{
std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
std::lock_guard<std::mutex> Guard{m_AtlasesMtx};
cache_it = m_Atlases.find(Fmt);
if (cache_it == m_Atlases.end())
return nullptr;
Expand All @@ -341,7 +341,7 @@ ITexture* ResourceManager::GetTexture(TEXTURE_FORMAT Fmt, IRenderDevice* pDevice
TextureDesc ResourceManager::GetAtlasDesc(TEXTURE_FORMAT Fmt)
{
{
std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
std::lock_guard<std::mutex> Guard{m_AtlasesMtx};

auto cache_it = m_Atlases.find(Fmt);
if (cache_it != m_Atlases.end())
Expand All @@ -357,7 +357,7 @@ TextureDesc ResourceManager::GetAtlasDesc(TEXTURE_FORMAT Fmt)
Uint32 ResourceManager::GetAllocationAlignment(TEXTURE_FORMAT Fmt, Uint32 Width, Uint32 Height)
{
{
std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
std::lock_guard<std::mutex> Guard{m_AtlasesMtx};

auto cache_it = m_Atlases.find(Fmt);
if (cache_it != m_Atlases.end())
Expand All @@ -381,7 +381,7 @@ DynamicTextureAtlasUsageStats ResourceManager::GetAtlasUsageStats(TEXTURE_FORMAT
{
DynamicTextureAtlasUsageStats Stats;
{
std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
std::lock_guard<std::mutex> Guard{m_AtlasesMtx};
if (Fmt != TEX_FORMAT_UNKNOWN)
{
auto cache_it = m_Atlases.find(Fmt);
Expand Down Expand Up @@ -410,7 +410,7 @@ VertexPoolUsageStats ResourceManager::GetVertexPoolUsageStats(const VertexLayout
{
VertexPoolUsageStats Stats;
{
std::lock_guard<std::mutex> Lock{m_VertexPoolsMtx};
std::lock_guard<std::mutex> Guard{m_VertexPoolsMtx};
if (Key != VertexLayoutKey{})
{
auto pool_it = m_VertexPools.find(Key);
Expand All @@ -436,6 +436,53 @@ VertexPoolUsageStats ResourceManager::GetVertexPoolUsageStats(const VertexLayout
return Stats;
}

void ResourceManager::TransitionResourceStates(IRenderDevice* pDevice, IDeviceContext* pContext, const TransitionResourceStatesInfo& Info)
{
m_Barriers.clear();

if (Info.VertexBuffers.NewState != RESOURCE_STATE_UNKNOWN)
{
std::lock_guard<std::mutex> Guard{m_VertexPoolsMtx};
for (auto it : m_VertexPools)
{
const auto& pPool = it.second;
const auto& Desc = pPool->GetDesc();
for (Uint32 elem = 0; elem < Desc.NumElements; ++elem)
{
if (auto* pVertBuffer = pPool->GetBuffer(elem, pDevice, pContext))
{
m_Barriers.emplace_back(pVertBuffer, Info.VertexBuffers.OldState, Info.VertexBuffers.NewState, Info.VertexBuffers.Flags);
}
}
}
}

if (Info.IndexBuffer.NewState != RESOURCE_STATE_UNKNOWN)
{
if (auto* pIndexBuffer = GetIndexBuffer(pDevice, pContext))
{
m_Barriers.emplace_back(pIndexBuffer, Info.IndexBuffer.OldState, Info.IndexBuffer.NewState, Info.IndexBuffer.Flags);
}
}

if (Info.TextureAtlases.NewState != RESOURCE_STATE_UNKNOWN)
{
std::lock_guard<std::mutex> Guard{m_AtlasesMtx};
for (auto it : m_Atlases)
{
if (auto* pTexture = it.second->GetTexture(pDevice, pContext))
{
m_Barriers.emplace_back(pTexture, Info.TextureAtlases.OldState, Info.TextureAtlases.NewState, Info.TextureAtlases.Flags);
}
}
}

if (!m_Barriers.empty())
{
pContext->TransitionResourceStates(static_cast<Uint32>(m_Barriers.size()), m_Barriers.data());
}
}

} // namespace GLTF

} // namespace Diligent

0 comments on commit c734bab

Please sign in to comment.