Vulkan: Refactor command buffer and introduce command pool
This commit is contained in:
@@ -1208,7 +1208,8 @@ namespace Nz
|
||||
template<typename Block, class Allocator>
|
||||
Block Bitset<Block, Allocator>::GetLastBlockMask() const
|
||||
{
|
||||
return (Block(1U) << GetBitIndex(m_bitCount)) - 1U;
|
||||
std::size_t bitIndex = GetBitIndex(m_bitCount);
|
||||
return (bitIndex) ? (Block(1U) << bitIndex) - 1U : fullBitMask;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1218,9 +1219,7 @@ namespace Nz
|
||||
template<typename Block, class Allocator>
|
||||
void Bitset<Block, Allocator>::ResetExtraBits()
|
||||
{
|
||||
Block mask = GetLastBlockMask();
|
||||
if (mask)
|
||||
m_blocks.back() &= mask;
|
||||
m_blocks.back() &= GetLastBlockMask();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <Nazara/Renderer/CommandBuffer.hpp>
|
||||
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
||||
#include <Nazara/Renderer/CommandPool.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/DebugDrawer.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
|
||||
37
include/Nazara/Renderer/CommandPool.hpp
Normal file
37
include/Nazara/Renderer/CommandPool.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_COMMANDPOOL_HPP
|
||||
#define NAZARA_COMMANDPOOL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <functional>
|
||||
#include <memory> //< temporary
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class CommandBuffer;
|
||||
class CommandBufferBuilder;
|
||||
|
||||
class NAZARA_RENDERER_API CommandPool
|
||||
{
|
||||
public:
|
||||
CommandPool() = default;
|
||||
CommandPool(const CommandPool&) = delete;
|
||||
CommandPool(CommandPool&&) = default;
|
||||
virtual ~CommandPool();
|
||||
|
||||
virtual std::unique_ptr<CommandBuffer> BuildCommandBuffer(const std::function<void(CommandBufferBuilder& builder)>& callback) = 0;
|
||||
|
||||
CommandPool& operator=(const CommandPool&) = delete;
|
||||
CommandPool& operator=(CommandPool&&) = default;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Renderer/CommandPool.inl>
|
||||
|
||||
#endif // NAZARA_COMMANDPOOL_HPP
|
||||
12
include/Nazara/Renderer/CommandPool.inl
Normal file
12
include/Nazara/Renderer/CommandPool.inl
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/CommandPool.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Renderer/DebugOff.hpp>
|
||||
@@ -69,6 +69,23 @@ namespace Nz
|
||||
using ShaderStageTypeFlags = Flags<ShaderStageType>;
|
||||
|
||||
constexpr ShaderStageTypeFlags ShaderStageType_All = ShaderStageType::Fragment | ShaderStageType::Vertex;
|
||||
|
||||
enum class QueueType
|
||||
{
|
||||
Compute,
|
||||
Graphics,
|
||||
Transfer,
|
||||
|
||||
Max = Transfer
|
||||
};
|
||||
|
||||
template<>
|
||||
struct EnumAsFlags<QueueType>
|
||||
{
|
||||
static constexpr QueueType max = QueueType::Max;
|
||||
};
|
||||
|
||||
using QueueTypeFlags = Flags<QueueType>;
|
||||
}
|
||||
|
||||
#endif // NAZARA_ENUMS_RENDERER_HPP
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class CommandPool;
|
||||
class ShaderStageImpl;
|
||||
|
||||
class NAZARA_RENDERER_API RenderDevice
|
||||
@@ -29,6 +30,7 @@ namespace Nz
|
||||
virtual ~RenderDevice();
|
||||
|
||||
virtual std::unique_ptr<AbstractBuffer> InstantiateBuffer(BufferType type) = 0;
|
||||
virtual std::unique_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) = 0;
|
||||
virtual std::unique_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) = 0;
|
||||
virtual std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) = 0;
|
||||
virtual std::shared_ptr<ShaderStageImpl> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) = 0;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace Nz
|
||||
@@ -23,11 +24,11 @@ namespace Nz
|
||||
RenderImage() = default;
|
||||
virtual ~RenderImage();
|
||||
|
||||
virtual void Execute(const std::function<void(CommandBufferBuilder& builder)>& callback, bool isGraphical) = 0;
|
||||
virtual void Execute(const std::function<void(CommandBufferBuilder& builder)>& callback, QueueTypeFlags queueTypeFlags) = 0;
|
||||
|
||||
virtual UploadPool& GetUploadPool() = 0;
|
||||
|
||||
virtual void SubmitCommandBuffer(CommandBuffer* commandBuffer, bool isGraphical) = 0;
|
||||
virtual void SubmitCommandBuffer(CommandBuffer* commandBuffer, QueueTypeFlags queueTypeFlags) = 0;
|
||||
|
||||
virtual void Present() = 0;
|
||||
|
||||
|
||||
@@ -13,12 +13,10 @@
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||
#include <Nazara/Renderer/RenderWindowParameters.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class CommandBuffer;
|
||||
class CommandBufferBuilder;
|
||||
class CommandPool;
|
||||
class RendererImpl;
|
||||
class RenderImage;
|
||||
class RenderSurface;
|
||||
@@ -31,9 +29,8 @@ namespace Nz
|
||||
|
||||
virtual RenderImage& Acquire() = 0;
|
||||
|
||||
virtual std::unique_ptr<CommandBuffer> BuildCommandBuffer(const std::function<void(CommandBufferBuilder& builder)>& callback) = 0;
|
||||
|
||||
virtual bool Create(RendererImpl* renderer, RenderSurface* surface, const Vector2ui& size, const RenderWindowParameters& parameters) = 0;
|
||||
virtual std::unique_ptr<CommandPool> CreateCommandPool(QueueType queueType) = 0;
|
||||
|
||||
virtual std::shared_ptr<RenderDevice> GetRenderDevice() = 0;
|
||||
};
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <Nazara/VulkanRenderer/VulkanBuffer.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanCommandBuffer.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanCommandBufferBuilder.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanCommandPool.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanDevice.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderer.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderImage.hpp>
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
38
include/Nazara/VulkanRenderer/VulkanCommandPool.hpp
Normal file
38
include/Nazara/VulkanRenderer/VulkanCommandPool.hpp
Normal 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
|
||||
28
include/Nazara/VulkanRenderer/VulkanCommandPool.inl
Normal file
28
include/Nazara/VulkanRenderer/VulkanCommandPool.inl
Normal 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>
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user