From 79af7d3c0053eb4d7fc673c449ef65c8f594233b Mon Sep 17 00:00:00 2001 From: Yuriy Toporovskyy Date: Thu, 5 Aug 2021 17:47:19 -0400 Subject: [PATCH] Make the maximum amount of vmem available for skinning related things configurable at runtime Signed-off-by: Yuriy Toporovskyy --- .../SkinnedMeshOutputStreamManager.cpp | 33 ++++++++++++++++++- .../SkinnedMeshOutputStreamManager.h | 3 ++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshOutputStreamManager.cpp b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshOutputStreamManager.cpp index c4eac30431..ffbe850160 100644 --- a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshOutputStreamManager.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshOutputStreamManager.cpp @@ -8,6 +8,8 @@ #include +#include + #include #include @@ -72,11 +74,36 @@ namespace AZ creator.End(m_bufferAsset); } + AZ_CVAR( + int, + r_skinnedMeshInstanceMemoryPoolSize, + 256, + nullptr, + AZ::ConsoleFunctorFlags::NeedsReload, + "The amount of memory in Mb available for all actor skinning data. Note that this must only be set once at application startup" + ); + void SkinnedMeshOutputStreamManager::Init() { + } + + void SkinnedMeshOutputStreamManager::EnsureInit() const + { + const_cast(this)->EnsureInit(); + } + + void SkinnedMeshOutputStreamManager::EnsureInit() + { + if (!m_needsInit) + { + return; + } + m_needsInit = false; + // 256mb supports roughly 42 character instances at 100,000 vertices per character x 64 bytes per vertex (12 byte position + 12 byte previous frame position + 12 byte normal + 16 byte tangent + 12 byte bitangent) // This includes only the output of the skinning compute shader, not the input buffers or bone transforms - m_sizeInBytes = 256u * (1024u * 1024u); + const AZ::u64 sizeInMb = r_skinnedMeshInstanceMemoryPoolSize; + m_sizeInBytes = AZ::GetMax(sizeInMb, 256ull) * (1024u * 1024u); CalculateAlignment(); @@ -90,6 +117,8 @@ namespace AZ RHI::VirtualAddress result; { AZStd::lock_guard lock(m_allocatorMutex); + + EnsureInit(); result = m_freeListAllocator.Allocate(byteCount, m_alignment); } @@ -129,11 +158,13 @@ namespace AZ Data::Asset SkinnedMeshOutputStreamManager::GetBufferAsset() const { + EnsureInit(); return m_bufferAsset; } Data::Instance SkinnedMeshOutputStreamManager::GetBuffer() { + EnsureInit(); if (!m_buffer) { m_buffer = RPI::Buffer::FindOrCreate(m_bufferAsset); diff --git a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshOutputStreamManager.h b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshOutputStreamManager.h index 3cec34a2e2..6009a62362 100644 --- a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshOutputStreamManager.h +++ b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshOutputStreamManager.h @@ -46,6 +46,8 @@ namespace AZ // SystemTickBus void OnSystemTick() override; + void EnsureInit() const; + void EnsureInit(); void GarbageCollect(); void CalculateAlignment(); void CreateBufferAsset(); @@ -58,6 +60,7 @@ namespace AZ size_t m_sizeInBytes = 0; bool m_memoryWasFreed = false; bool m_broadcastMemoryAvailableEvent = false; + bool m_needsInit = true; }; } // namespace Render } // namespace AZ