From f87a0d5c012c01faeba8814637c39a0ba8cef69e Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 10 May 2018 09:35:39 -0700 Subject: Added VulkanDescriptorPool --- Graphics/GraphicsEngineVulkan/CMakeLists.txt | 2 + .../include/VulkanUtilities/VulkanDescriptorPool.h | 62 ++++++++++++++++ .../include/VulkanUtilities/VulkanLogicalDevice.h | 3 + .../src/VulkanUtilities/VulkanDescriptorPool.cpp | 85 ++++++++++++++++++++++ .../src/VulkanUtilities/VulkanLogicalDevice.cpp | 25 +++++++ 5 files changed, 177 insertions(+) create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDescriptorPool.h create mode 100644 Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDescriptorPool.cpp (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt index a1a4dfa6..7d489fc1 100644 --- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt +++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt @@ -34,6 +34,7 @@ set(VULKAN_UTILS_INCLUDE include/VulkanUtilities/VulkanCommandBuffer.h include/VulkanUtilities/VulkanCommandBufferPool.h include/VulkanUtilities/VulkanDebug.h + include/VulkanUtilities/VulkanDescriptorPool.h include/VulkanUtilities/VulkanFencePool.h include/VulkanUtilities/VulkanInstance.h include/VulkanUtilities/VulkanLogicalDevice.h @@ -89,6 +90,7 @@ set(VULKAN_UTILS_SRC src/VulkanUtilities/VulkanCommandBuffer.cpp src/VulkanUtilities/VulkanCommandBufferPool.cpp src/VulkanUtilities/VulkanDebug.cpp + src/VulkanUtilities/VulkanDescriptorPool.cpp src/VulkanUtilities/VulkanFencePool.cpp src/VulkanUtilities/VulkanInstance.cpp src/VulkanUtilities/VulkanLogicalDevice.cpp diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDescriptorPool.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDescriptorPool.h new file mode 100644 index 00000000..23b40445 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDescriptorPool.h @@ -0,0 +1,62 @@ +/* Copyright 2015-2018 Egor Yusov +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. +* +* In no event and under no legal theory, whether in tort (including negligence), +* contract, or otherwise, unless required by applicable law (such as deliberate +* and grossly negligent acts) or agreed to in writing, shall any Contributor be +* liable for any damages, including any direct, indirect, special, incidental, +* or consequential damages of any character arising as a result of this License or +* out of the use or inability to use the software (including but not limited to damages +* for loss of goodwill, work stoppage, computer failure or malfunction, or any and +* all other commercial damages or losses), even if such Contributor has been advised +* of the possibility of such damages. +*/ + +#pragma once + +#include +#include +#include "vulkan.h" +#include "VulkanLogicalDevice.h" +#include "VulkanObjectWrappers.h" + +namespace VulkanUtilities +{ + class VulkanDescriptorPool + { + public: + VulkanDescriptorPool(std::shared_ptr LogicalDevice, + const VkDescriptorPoolCreateInfo &DescriptorPoolCI); + VulkanDescriptorPool(const VulkanDescriptorPool&) = delete; + VulkanDescriptorPool(VulkanDescriptorPool&&) = delete; + VulkanDescriptorPool& operator = (const VulkanDescriptorPool&) = delete; + VulkanDescriptorPool& operator = (VulkanDescriptorPool&&) = delete; + ~VulkanDescriptorPool(); + + VkDescriptorSet AllocateDescriptorSet(VkDescriptorSetLayout SetLayout, const char* DebugName = ""); + void DisposeDescriptorSet(VkDescriptorSet DescrSet, uint64_t FenceValue); + void ReleaseDiscardedSets(uint64_t LastCompletedFence); + + DescriptorPoolWrapper&& Release(); + + private: + // Shared point to logical device must be defined before the command pool + std::shared_ptr m_LogicalDevice; + DescriptorPoolWrapper m_Pool; + + // fist - the fence value associated with the command buffer referencing the set + // when it was executed + // second - the descriptor set + typedef std::pair QueueElemType; + std::deque< QueueElemType > m_DiscardedSets; + }; +} diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h index ab6f39b9..dbc62d2f 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h @@ -81,6 +81,7 @@ namespace VulkanUtilities SemaphoreWrapper CreateSemaphore(const VkSemaphoreCreateInfo &SemaphoreCI, const char *DebugName = "")const; VkCommandBuffer AllocateVkCommandBuffer(const VkCommandBufferAllocateInfo &AllocInfo, const char *DebugName = "")const; + VkDescriptorSet AllocateVkDescriptorSet(const VkDescriptorSetAllocateInfo &AllocInfo, const char *DebugName = "")const; void ReleaseVulkanObject(CommandPoolWrapper&& CmdPool)const; void ReleaseVulkanObject(BufferWrapper&& Buffer)const; @@ -99,6 +100,8 @@ namespace VulkanUtilities void ReleaseVulkanObject(DescriptorSetLayoutWrapper&& DescriptorSetLayout)const; void ReleaseVulkanObject(SemaphoreWrapper&& Semaphore)const; + void FreeDescriptorSet(VkDescriptorPool Pool, VkDescriptorSet Set)const; + VkMemoryRequirements GetBufferMemoryRequirements(VkBuffer vkBuffer)const; VkMemoryRequirements GetImageMemoryRequirements (VkImage vkImage )const; diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDescriptorPool.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDescriptorPool.cpp new file mode 100644 index 00000000..c08e8c9d --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDescriptorPool.cpp @@ -0,0 +1,85 @@ +/* Copyright 2015-2018 Egor Yusov +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. +* +* In no event and under no legal theory, whether in tort (including negligence), +* contract, or otherwise, unless required by applicable law (such as deliberate +* and grossly negligent acts) or agreed to in writing, shall any Contributor be +* liable for any damages, including any direct, indirect, special, incidental, +* or consequential damages of any character arising as a result of this License or +* out of the use or inability to use the software (including but not limited to damages +* for loss of goodwill, work stoppage, computer failure or malfunction, or any and +* all other commercial damages or losses), even if such Contributor has been advised +* of the possibility of such damages. +*/ +#include + +#include "VulkanUtilities/VulkanDescriptorPool.h" +#include "VulkanUtilities/VulkanDebug.h" +#include "Errors.h" +#include "DebugUtilities.h" +#include "VulkanErrors.h" + +namespace VulkanUtilities +{ + VulkanDescriptorPool::VulkanDescriptorPool(std::shared_ptr LogicalDevice, + const VkDescriptorPoolCreateInfo &DescriptorPoolCI) : + m_LogicalDevice(LogicalDevice) + { + VERIFY_EXPR(DescriptorPoolCI.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO); + m_Pool = m_LogicalDevice->CreateDescriptorPool(DescriptorPoolCI); + VERIFY_EXPR(m_Pool != VK_NULL_HANDLE); + } + + VulkanDescriptorPool::~VulkanDescriptorPool() + { + m_Pool.Release(); + } + + VkDescriptorSet VulkanDescriptorPool::AllocateDescriptorSet(VkDescriptorSetLayout SetLayout, const char* DebugName) + { + VkDescriptorSetAllocateInfo DescrSetAllocInfo = {}; + DescrSetAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + DescrSetAllocInfo.pNext = nullptr; + DescrSetAllocInfo.descriptorPool = m_Pool; + DescrSetAllocInfo.descriptorSetCount = 1; + DescrSetAllocInfo.pSetLayouts = &SetLayout; + return m_LogicalDevice->AllocateVkDescriptorSet(DescrSetAllocInfo, DebugName); + } + + void VulkanDescriptorPool::ReleaseDiscardedSets(uint64_t LastCompletedFence) + { + // Pick the oldest descriptor set at the front of the deque. + // .first is the fence value that was signaled AFTER the command buffer referencing + // the set has been submitted. If LastCompletedFence is at least this value, the buffer + // is now finished, and the set can be safely released + while (!m_DiscardedSets.empty() && LastCompletedFence >= m_DiscardedSets.front().first ) + { + m_LogicalDevice->FreeDescriptorSet(m_Pool, m_DiscardedSets.front().second); + m_DiscardedSets.pop_front(); + } + } + + void VulkanDescriptorPool::DisposeDescriptorSet(VkDescriptorSet DescrSet, uint64_t FenceValue) + { + // FenceValue is the value that was signaled by the command queue after it + // executed the command buffer + m_DiscardedSets.emplace_back(FenceValue, DescrSet); + } + + DescriptorPoolWrapper&& VulkanDescriptorPool::Release() + { + m_LogicalDevice.reset(); + VERIFY(m_DiscardedSets.empty(), "Discarded sets are not released"); + m_DiscardedSets.clear(); + return std::move(m_Pool); + } +} diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp index 57204616..39ec1011 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp @@ -256,6 +256,25 @@ namespace VulkanUtilities return CmdBuff; } + VkDescriptorSet VulkanLogicalDevice::AllocateVkDescriptorSet(const VkDescriptorSetAllocateInfo &AllocInfo, const char *DebugName)const + { + VERIFY_EXPR(AllocInfo.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO); + VERIFY_EXPR(AllocInfo.descriptorSetCount == 1); + + if (DebugName == nullptr) + DebugName = ""; + + VkDescriptorSet DescrSet = VK_NULL_HANDLE; + auto err = vkAllocateDescriptorSets(m_VkDevice, &AllocInfo, &DescrSet); + if(err != VK_SUCCESS) + return VK_NULL_HANDLE; + + if (DebugName != nullptr && *DebugName != 0) + SetDescriptorSetName(m_VkDevice, DescrSet, DebugName); + + return DescrSet; + } + void VulkanLogicalDevice::ReleaseVulkanObject(CommandPoolWrapper &&CmdPool)const { vkDestroyCommandPool(m_VkDevice, CmdPool.m_VkObject, m_VkAllocator); @@ -353,6 +372,12 @@ namespace VulkanUtilities } + void VulkanLogicalDevice::FreeDescriptorSet(VkDescriptorPool Pool, VkDescriptorSet Set)const + { + VERIFY_EXPR(Pool != VK_NULL_HANDLE && Set != VK_NULL_HANDLE); + vkFreeDescriptorSets(m_VkDevice, Pool, 1, &Set); + } + -- cgit v1.2.3