From b1081bd26cbcc1d999bbc91baa7ef43827492d75 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Wed, 10 Jul 2024 17:03:45 +0200 Subject: [PATCH] Cleanup ResourceManager --- openVulkanoCpp/Data/Containers/Array.hpp | 9 ++ .../Vulkan/Resources/ResourceManager.cpp | 85 +++++++++---------- .../Vulkan/Resources/ResourceManager.hpp | 14 +-- 3 files changed, 57 insertions(+), 51 deletions(-) diff --git a/openVulkanoCpp/Data/Containers/Array.hpp b/openVulkanoCpp/Data/Containers/Array.hpp index 4df03ec..2c7057e 100644 --- a/openVulkanoCpp/Data/Containers/Array.hpp +++ b/openVulkanoCpp/Data/Containers/Array.hpp @@ -98,6 +98,15 @@ namespace OpenVulkano Fill(defaultValue); } + template + Array(size_t size, ARGS... args) : size(size), data(MakeBuffer(size)) + { + for(size_t i = 0; i < size; i++) + { + new (&data[i]) T(args...); + } + } + ~Array() noexcept { ClearData(); diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index 8fbb8cb..6e3075c 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -26,6 +26,30 @@ namespace OpenVulkano::Vulkan { ResourceManager* ResourceManager::INSTANCE; + struct ResourceManager::FrameResources + { + vk::Device device; + vk::CommandPool cmdPool; + vk::CommandBuffer cmdBuffer; + vk::Semaphore semaphore; + + FrameResources(Device* device) + { + this->device = device->device; + cmdPool = this->device.createCommandPool({ {}, device->queueIndices.transfer }); + cmdBuffer = this->device.allocateCommandBuffers({ cmdPool, vk::CommandBufferLevel::ePrimary, 1 })[0]; + semaphore = this->device.createSemaphore({}); + } + + ~FrameResources() + { + device.freeCommandBuffers(cmdPool, 1, &cmdBuffer); + device.destroyCommandPool(cmdPool); + device.destroy(semaphore); + } + }; + + ResourceManager::ResourceManager() { static_assert(sizeof(DescriptorSetLayoutBinding) == sizeof(vk::DescriptorSetLayoutBinding)); @@ -40,20 +64,12 @@ namespace OpenVulkano::Vulkan void ResourceManager::Init(Context* context, int buffers) { this->context = context; - this->device = context->device->device; - this->buffers = buffers; + device = context->device->device; uniformBufferAlignment = context->device->properties.limits.minUniformBufferOffsetAlignment; + + frameResources = Array(static_cast(buffers), context->device.get()); - cmdPools = new vk::CommandPool[buffers]; - cmdBuffers = new vk::CommandBuffer[buffers]; - semaphores = new vk::Semaphore[buffers]; - for (int i = 0; i < buffers; i++) - { - cmdPools[i] = this->device.createCommandPool({ {}, context->device->queueIndices.transfer }); - cmdBuffers[i] = this->device.allocateCommandBuffers({ cmdPools[i], vk::CommandBufferLevel::ePrimary, 1 })[0]; - semaphores[i] = this->device.createSemaphore({}); - } toFree.resize(buffers); transferQueue = this->device.getQueue(context->device->queueIndices.transfer, 0); @@ -81,15 +97,7 @@ namespace OpenVulkano::Vulkan void ResourceManager::Close() { transferQueue.waitIdle(); - for (int i = 0; i < buffers; i++) - { - device.freeCommandBuffers(cmdPools[i], 1, &cmdBuffers[i]); - device.destroyCommandPool(cmdPools[i]); - device.destroy(semaphores[i]); - } - cmdPools = nullptr; - cmdBuffers = nullptr; - semaphores = nullptr; + transferQueue = nullptr; geometries.clear(); nodes.clear(); device.destroyDescriptorPool(descriptorPool); @@ -103,26 +111,25 @@ namespace OpenVulkano::Vulkan } samplerCache.clear(); shaders.clear(); - cmdBuffers = nullptr; - cmdPools = nullptr; - transferQueue = nullptr; device = nullptr; } + vk::CommandBuffer& ResourceManager::GetCmdBuffer() { return frameResources[currentBuffer].cmdBuffer; } + void ResourceManager::StartFrame(uint64_t frameId) { currentBuffer = frameId; FreeBuffers(); - device.resetCommandPool(cmdPools[currentBuffer], {}); - cmdBuffers[currentBuffer].begin({ vk::CommandBufferUsageFlagBits::eOneTimeSubmit }); + device.resetCommandPool(frameResources[currentBuffer].cmdPool, {}); + GetCmdBuffer().begin({ vk::CommandBufferUsageFlagBits::eOneTimeSubmit }); } vk::Semaphore ResourceManager::EndFrame() { - cmdBuffers[currentBuffer].end(); - vk::SubmitInfo si = { 0, nullptr, nullptr, 1, &cmdBuffers[currentBuffer], 1, &semaphores[currentBuffer] }; + GetCmdBuffer().end(); + vk::SubmitInfo si = { 0, nullptr, nullptr, 1, &frameResources[currentBuffer].cmdBuffer, 1, &frameResources[currentBuffer].semaphore }; transferQueue.submit(1, &si, vk::Fence()); - return semaphores[currentBuffer]; + return frameResources[currentBuffer].semaphore; } void ResourceManager::Resize() @@ -254,7 +261,7 @@ namespace OpenVulkano::Vulkan void ResourceManager::RemoveShader(VulkanShader* shader) { - if (!cmdPools) return; + if (!transferQueue) return; const std::unique_lock lock(mutex); std::vector>::iterator object = find_if(shaders.begin(), shaders.end(), @@ -296,27 +303,15 @@ namespace OpenVulkano::Vulkan ManagedBuffer* uploadBuffer = CreateBuffer(size, vk::BufferUsageFlagBits::eTransferSrc, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible); uploadBuffer->Copy(data, size, 0); - image->SetLayout(cmdBuffers[currentBuffer], vk::ImageAspectFlagBits::eColor, vk::ImageLayout::eTransferDstOptimal); + image->SetLayout(GetCmdBuffer(), vk::ImageAspectFlagBits::eColor, vk::ImageLayout::eTransferDstOptimal); vk::BufferImageCopy region(0, 0, 0, { vk::ImageAspectFlagBits::eColor, 0, 0, 1 }, { 0, 0, 0 }, image->extent); - cmdBuffers[currentBuffer].copyBufferToImage(uploadBuffer->buffer, image->image, vk::ImageLayout::eTransferDstOptimal, 1, ®ion); + GetCmdBuffer().copyBufferToImage(uploadBuffer->buffer, image->image, vk::ImageLayout::eTransferDstOptimal, 1, ®ion); - /*vk::ImageMemoryBarrier barrier {}; - barrier.oldLayout = vk::ImageLayout::eUndefined; - barrier.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal; - barrier.image = image->image; - barrier.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; - barrier.subresourceRange.baseMipLevel = 0; - barrier.subresourceRange.levelCount = 1; - barrier.subresourceRange.baseArrayLayer = 0; - barrier.subresourceRange.layerCount = 1; - barrier.setSrcAccessMask({}); - barrier.setDstAccessMask(vk::AccessFlagBits::eTransferWrite);*/ - - image->SetLayout(cmdBuffers[currentBuffer], vk::ImageAspectFlagBits::eColor, vk::ImageLayout::eShaderReadOnlyOptimal, vk::ImageLayout::eTransferDstOptimal); + image->SetLayout(GetCmdBuffer(), vk::ImageAspectFlagBits::eColor, vk::ImageLayout::eShaderReadOnlyOptimal, vk::ImageLayout::eTransferDstOptimal); // TODO set access masks for mip and array layers - //cmdBuffers[currentBuffer].pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, 0, nullptr, 0, nullptr, 1, &barrier ); + //GetCmdBuffer().pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, 0, nullptr, 0, nullptr, 1, &barrier ); FreeBuffer(uploadBuffer); } diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp index 27f27c1..a3716df 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp @@ -49,12 +49,12 @@ namespace OpenVulkano friend UniformBuffer; friend VulkanTexture; + struct FrameResources; + Context* context; vk::Device device = nullptr; vk::Queue transferQueue = nullptr; - vk::CommandPool* cmdPools = nullptr; - vk::CommandBuffer* cmdBuffers = nullptr; - vk::Semaphore* semaphores = nullptr; + Array frameResources; std::vector> allocations; std::vector> shaders; std::vector> geometries; @@ -68,7 +68,9 @@ namespace OpenVulkano std::map descriptorSetLayoutCache; std::map samplerCache; - int buffers = -1, currentBuffer = -1; + int currentBuffer = -1; + + vk::CommandBuffer& GetCmdBuffer(); public: static ResourceManager* INSTANCE; @@ -122,10 +124,10 @@ namespace OpenVulkano ManagedBuffer* CreateDeviceOnlyBufferWithData(vk::DeviceSize size, vk::BufferUsageFlagBits usage, const void* data); - inline void RecordCopy(vk::Buffer src, vk::Buffer dest, vk::DeviceSize size) const + inline void RecordCopy(vk::Buffer src, vk::Buffer dest, vk::DeviceSize size) { vk::BufferCopy copyRegion = { 0, 0, size }; - cmdBuffers[currentBuffer].copyBuffer(src, dest, 1, ©Region); + GetCmdBuffer().copyBuffer(src, dest, 1, ©Region); } ManagedBuffer* CreateBuffer(vk::DeviceSize size, const vk::BufferUsageFlags& usage, const vk::MemoryPropertyFlags& properties);