Vulkan: Refactor command buffer and introduce command pool

This commit is contained in:
Lynix
2020-04-07 21:10:16 +02:00
parent f6d21d066e
commit 87f1209327
27 changed files with 313 additions and 85 deletions

View File

@@ -11,6 +11,7 @@
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/RendererImpl.hpp>
#include <Nazara/Renderer/RenderWindowImpl.hpp>
#include <Nazara/VulkanRenderer/Config.hpp>
@@ -40,9 +41,8 @@ namespace Nz
VulkanRenderImage& Acquire() override;
std::unique_ptr<CommandBuffer> BuildCommandBuffer(const std::function<void(CommandBufferBuilder& builder)>& callback) override;
bool Create(RendererImpl* renderer, RenderSurface* surface, const Vector2ui& size, const RenderWindowParameters& parameters) override;
std::unique_ptr<CommandPool> CreateCommandPool(QueueType queueType) override;
inline const Vk::Framebuffer& GetFrameBuffer(UInt32 imageIndex) const override;
inline UInt32 GetFramebufferCount() const override;
@@ -77,12 +77,12 @@ namespace Nz
std::shared_ptr<VulkanDevice> m_device;
std::vector<ImageData> m_imageData;
std::vector<VulkanRenderImage> m_concurrentImageData;
Vk::CommandPool m_graphicsCommandPool;
Vk::DeviceMemory m_depthBufferMemory;
Vk::Image m_depthBuffer;
Vk::ImageView m_depthBufferView;
Vk::QueueHandle m_graphicsQueue;
Vk::QueueHandle m_presentQueue;
Vk::QueueHandle m_transferQueue;
Vk::Swapchain m_swapchain;
};
}

View File

@@ -36,7 +36,7 @@ namespace Nz
~Vulkan() = delete;
static std::shared_ptr<VulkanDevice> CreateDevice(const Vk::PhysicalDevice& deviceInfo);
static std::shared_ptr<VulkanDevice> CreateDevice(const Vk::PhysicalDevice& deviceInfo, const Vk::Surface& surface, UInt32* graphicsFamilyIndex, UInt32* presentableFamilyIndex);
static std::shared_ptr<VulkanDevice> CreateDevice(const Vk::PhysicalDevice& deviceInfo, const Vk::Surface& surface, UInt32* graphicsFamilyIndex, UInt32* presentableFamilyIndex, UInt32* transferFamilyIndex);
static std::shared_ptr<VulkanDevice> CreateDevice(const Vk::PhysicalDevice& deviceInfo, const QueueFamily* queueFamilies, std::size_t queueFamilyCount);
static Vk::Instance& GetInstance();
@@ -49,7 +49,7 @@ namespace Nz
static bool IsInitialized();
static std::shared_ptr<VulkanDevice> SelectDevice(const Vk::PhysicalDevice& deviceInfo);
static std::shared_ptr<VulkanDevice> SelectDevice(const Vk::PhysicalDevice& deviceInfo, const Vk::Surface& surface, UInt32* graphicsFamilyIndex, UInt32* presentableFamilyIndex);
static std::shared_ptr<VulkanDevice> SelectDevice(const Vk::PhysicalDevice& deviceInfo, const Vk::Surface& surface, UInt32* graphicsFamilyIndex, UInt32* presentableFamilyIndex, UInt32* transferFamilyIndex);
static void Uninitialize();

View File

@@ -0,0 +1,38 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_VULKANRENDERER_VULKANCOMMANDPOOL_HPP
#define NAZARA_VULKANRENDERER_VULKANCOMMANDPOOL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/CommandPool.hpp>
#include <Nazara/VulkanRenderer/Config.hpp>
#include <Nazara/VulkanRenderer/Wrapper/CommandPool.hpp>
namespace Nz
{
class NAZARA_VULKANRENDERER_API VulkanCommandPool final : public CommandPool
{
public:
inline VulkanCommandPool(Vk::Device& device, QueueType queueType);
inline VulkanCommandPool(Vk::Device& device, UInt32 queueFamilyIndex);
VulkanCommandPool(const VulkanCommandPool&) = delete;
VulkanCommandPool(VulkanCommandPool&&) noexcept = default;
~VulkanCommandPool() = default;
std::unique_ptr<CommandBuffer> BuildCommandBuffer(const std::function<void(CommandBufferBuilder& builder)>& callback) override;
VulkanCommandPool& operator=(const VulkanCommandPool&) = delete;
VulkanCommandPool& operator=(VulkanCommandPool&&) = delete;
private:
Vk::CommandPool m_commandPool;
};
}
#include <Nazara/VulkanRenderer/VulkanCommandPool.inl>
#endif // NAZARA_VULKANRENDERER_VULKANCOMMANDPOOL_HPP

View File

@@ -0,0 +1,28 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Vulkan Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/VulkanRenderer/VulkanCommandPool.hpp>
#include <stdexcept>
#include <Nazara/VulkanRenderer/Debug.hpp>
namespace Nz
{
inline VulkanCommandPool::VulkanCommandPool(Vk::Device& device, QueueType queueType)
{
UInt32 queueFamilyIndex = device.GetDefaultFamilyIndex(queueType);
if (queueFamilyIndex == Vk::Device::InvalidQueue)
throw std::runtime_error("QueueType " + std::to_string(UnderlyingCast(queueType)) + " is not supported");
if (!m_commandPool.Create(device, queueFamilyIndex))
throw std::runtime_error("Failed to create command pool: " + TranslateVulkanError(m_commandPool.GetLastErrorCode()));
}
inline VulkanCommandPool::VulkanCommandPool(Vk::Device& device, UInt32 queueFamilyIndex)
{
if (!m_commandPool.Create(device, queueFamilyIndex))
throw std::runtime_error("Failed to create command pool: " + TranslateVulkanError(m_commandPool.GetLastErrorCode()));
}
}
#include <Nazara/VulkanRenderer/DebugOff.hpp>

View File

@@ -24,6 +24,7 @@ namespace Nz
~VulkanDevice();
std::unique_ptr<AbstractBuffer> InstantiateBuffer(BufferType type) override;
std::unique_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) override;
std::unique_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
std::shared_ptr<ShaderStageImpl> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) override;

View File

@@ -28,7 +28,7 @@ namespace Nz
VulkanRenderImage(VulkanRenderImage&&) noexcept = default;
~VulkanRenderImage();
void Execute(const std::function<void(CommandBufferBuilder& builder)>& callback, bool isGraphical) override;
void Execute(const std::function<void(CommandBufferBuilder& builder)>& callback, QueueTypeFlags queueTypeFlags) override;
inline Vk::Fence& GetInFlightFence();
inline Vk::Semaphore& GetImageAvailableSemaphore();
@@ -36,8 +36,8 @@ namespace Nz
inline Vk::Semaphore& GetRenderFinishedSemaphore();
VulkanUploadPool& GetUploadPool() override;
void SubmitCommandBuffer(CommandBuffer* commandBuffer, bool isGraphical) override;
void SubmitCommandBuffer(VkCommandBuffer commandBuffer, bool isGraphical);
void SubmitCommandBuffer(CommandBuffer* commandBuffer, QueueTypeFlags queueTypeFlags) override;
void SubmitCommandBuffer(VkCommandBuffer commandBuffer, QueueTypeFlags queueTypeFlags);
void Present() override;

View File

@@ -8,10 +8,13 @@
#define NAZARA_VULKANRENDERER_VKDEVICE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/VulkanRenderer/Config.hpp>
#include <Nazara/VulkanRenderer/Wrapper/Loader.hpp>
#include <Nazara/VulkanRenderer/Wrapper/PhysicalDevice.hpp>
#include <vulkan/vulkan.h>
#include <array>
#include <memory>
#include <unordered_set>
@@ -38,7 +41,7 @@ namespace Nz
Device(Device&&) = delete;
~Device();
AutoCommandBuffer AllocateTransferCommandBuffer();
AutoCommandBuffer AllocateCommandBuffer(QueueType queueType);
bool Create(const Vk::PhysicalDevice& deviceInfo, const VkDeviceCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr);
inline void Destroy();
@@ -54,7 +57,7 @@ namespace Nz
inline VkPhysicalDevice GetPhysicalDevice() const;
inline const Vk::PhysicalDevice& GetPhysicalDeviceInfo() const;
inline UInt32 GetTransferQueueFamilyIndex() const;
inline UInt32 GetDefaultFamilyIndex(QueueType queueType) const;
inline bool IsExtensionLoaded(const std::string& extensionName);
inline bool IsLayerLoaded(const std::string& layerName);
@@ -99,6 +102,8 @@ namespace Nz
UInt32 timestampValidBits;
};
static constexpr UInt32 InvalidQueue = std::numeric_limits<UInt32>::max();
private:
void ResetPointers();
void WaitAndDestroyDevice();
@@ -107,6 +112,8 @@ namespace Nz
struct InternalData;
static constexpr std::size_t QueueCount = static_cast<std::size_t>(QueueType::Max) + 1;
std::unique_ptr<InternalData> m_internalData;
Instance& m_instance;
const Vk::PhysicalDevice* m_physicalDevice;
@@ -114,7 +121,7 @@ namespace Nz
VkDevice m_device;
VkResult m_lastErrorCode;
VmaAllocator m_memAllocator;
UInt32 m_transferQueueFamilyIndex;
std::array<UInt32, QueueCount> m_defaultQueues;
std::unordered_set<std::string> m_loadedExtensions;
std::unordered_set<std::string> m_loadedLayers;
std::vector<QueueFamilyInfo> m_enabledQueuesInfos;

View File

@@ -54,9 +54,9 @@ namespace Nz
return *m_physicalDevice;
}
inline UInt32 Device::GetTransferQueueFamilyIndex() const
inline UInt32 Device::GetDefaultFamilyIndex(QueueType queueType) const
{
return m_transferQueueFamilyIndex;
return m_defaultQueues[UnderlyingCast(queueType)];
}
inline bool Device::IsExtensionLoaded(const std::string& extensionName)