[Feat] (MG_Backend/DirectVulkan): unified transient buffer arena

This commit is contained in:
2026-03-20 13:56:12 +08:00
parent 9d1e8bd7cd
commit 7dfc2149d8
3 changed files with 12 additions and 65 deletions
@@ -20,9 +20,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
}
void VkBufferManager::Shutdown() {
m_vertexUploadArena.Shutdown();
m_indexUploadArena.Shutdown();
m_uniformUploadArena.Shutdown();
m_transientUploadArena.Shutdown();
m_initInfo = {};
}
@@ -30,76 +28,31 @@ namespace MobileGL::MG_Backend::DirectVulkan {
MOBILEGL_ASSERT(m_initInfo.allocator != nullptr, "VkBufferManager::RecreateTransientArenas requires initialized manager");
MOBILEGL_ASSERT(frameCount > 0, "VkBufferManager::RecreateTransientArenas requires non-zero frame count");
m_vertexUploadArena.Shutdown();
m_indexUploadArena.Shutdown();
m_uniformUploadArena.Shutdown();
m_transientUploadArena.Shutdown();
m_initInfo.frameCount = frameCount;
return InitializeTransientArenas();
}
void VkBufferManager::BeginFrame(Uint32 frameIndex) {
m_vertexUploadArena.BeginFrame(frameIndex);
m_indexUploadArena.BeginFrame(frameIndex);
m_uniformUploadArena.BeginFrame(frameIndex);
m_transientUploadArena.BeginFrame(frameIndex);
}
Bool VkBufferManager::UploadTransient(TransientBufferKind kind, Uint32 frameIndex, const void* data,
VkDeviceSize size, VkDeviceSize alignment, BufferSlice& outSlice) {
switch (kind) {
case TransientBufferKind::Vertex:
return m_vertexUploadArena.Upload(frameIndex, data, size, alignment, outSlice);
case TransientBufferKind::Index:
return m_indexUploadArena.Upload(frameIndex, data, size, alignment, outSlice);
case TransientBufferKind::Uniform:
return m_uniformUploadArena.Upload(frameIndex, data, size, alignment, outSlice);
default:
return false;
}
(void)kind;
return m_transientUploadArena.Upload(frameIndex, data, size, alignment, outSlice);
}
Bool VkBufferManager::InitializeTransientArenas() {
Bool ok = m_vertexUploadArena.Initialize({
return m_transientUploadArena.Initialize({
.allocator = m_initInfo.allocator,
.frameCount = m_initInfo.frameCount,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
.memoryUsage = m_initInfo.transientMemoryUsage,
.allocationFlags = m_initInfo.transientAllocationFlags,
.minBufferSize = m_initInfo.minVertexUploadBytes,
.minBufferSize = m_initInfo.minUploadBytes,
.persistentlyMapped = m_initInfo.transientPersistentMapping,
});
if (!ok) {
return false;
}
ok = m_indexUploadArena.Initialize({
.allocator = m_initInfo.allocator,
.frameCount = m_initInfo.frameCount,
.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
.memoryUsage = m_initInfo.transientMemoryUsage,
.allocationFlags = m_initInfo.transientAllocationFlags,
.minBufferSize = m_initInfo.minIndexUploadBytes,
.persistentlyMapped = m_initInfo.transientPersistentMapping,
});
if (!ok) {
m_vertexUploadArena.Shutdown();
return false;
}
ok = m_uniformUploadArena.Initialize({
.allocator = m_initInfo.allocator,
.frameCount = m_initInfo.frameCount,
.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
.memoryUsage = m_initInfo.transientMemoryUsage,
.allocationFlags = m_initInfo.transientAllocationFlags,
.minBufferSize = m_initInfo.minUniformUploadBytes,
.persistentlyMapped = m_initInfo.transientPersistentMapping,
});
if (!ok) {
m_vertexUploadArena.Shutdown();
m_indexUploadArena.Shutdown();
return false;
}
return true;
}
} // namespace MobileGL::MG_Backend::DirectVulkan
@@ -23,9 +23,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
struct VkBufferManagerInitInfo {
VmaAllocator allocator = nullptr;
Uint32 frameCount = 0;
VkDeviceSize minVertexUploadBytes = 4 * 1024 * 1024;
VkDeviceSize minIndexUploadBytes = 1 * 1024 * 1024;
VkDeviceSize minUniformUploadBytes = 4 * 1024 * 1024;
VkDeviceSize minUploadBytes = 4 * 1024 * 1024;
VmaMemoryUsage transientMemoryUsage = VMA_MEMORY_USAGE_AUTO;
VmaAllocationCreateFlags transientAllocationFlags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
Bool transientPersistentMapping = false;
@@ -47,8 +45,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
Bool InitializeTransientArenas();
VkBufferManagerInitInfo m_initInfo{};
BufferArena m_vertexUploadArena;
BufferArena m_indexUploadArena;
BufferArena m_uniformUploadArena;
BufferArena m_transientUploadArena;
};
} // namespace MobileGL::MG_Backend::DirectVulkan
@@ -291,9 +291,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
succeeded = m_bufferManager.Initialize({
.allocator = m_allocator,
.frameCount = m_frameContext.GetFrameCount(),
.minVertexUploadBytes = 4 * 1024 * 1024,
.minIndexUploadBytes = 1 * 1024 * 1024,
.minUniformUploadBytes = 4 * 1024 * 1024,
.minUploadBytes = 4 * 1024 * 1024,
.transientMemoryUsage = VMA_MEMORY_USAGE_AUTO,
.transientAllocationFlags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.transientPersistentMapping = false,