Replace DeviceHandle by references
and keep device alive until Vulkan is freed
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
#include <Nazara/VulkanRenderer/Vulkan.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanDevice.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanSurface.hpp>
|
||||
#include <array>
|
||||
#include <stdexcept>
|
||||
@@ -43,7 +44,7 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VkRenderWindow::Create(RendererImpl* renderer, RenderSurface* surface, const Vector2ui& size, const RenderWindowParameters& parameters)
|
||||
bool VkRenderWindow::Create(RendererImpl* /*renderer*/, RenderSurface* surface, const Vector2ui& size, const RenderWindowParameters& parameters)
|
||||
{
|
||||
m_physicalDevice = Vulkan::GetPhysicalDevices()[0].device;
|
||||
|
||||
@@ -74,8 +75,6 @@ namespace Nz
|
||||
|
||||
if (!parameters.depthFormats.empty())
|
||||
{
|
||||
const Vk::PhysicalDevice& deviceInfo = Vulkan::GetPhysicalDeviceInfo(m_physicalDevice);
|
||||
|
||||
for (PixelFormatType format : parameters.depthFormats)
|
||||
{
|
||||
switch (format)
|
||||
@@ -163,7 +162,7 @@ namespace Nz
|
||||
1U // uint32_t layers;
|
||||
};
|
||||
|
||||
if (!m_frameBuffers[i].Create(m_device, frameBufferCreate))
|
||||
if (!m_frameBuffers[i].Create(*m_device, frameBufferCreate))
|
||||
{
|
||||
NazaraError("Failed to create framebuffer for image #" + String::Number(i));
|
||||
return false;
|
||||
@@ -195,14 +194,14 @@ namespace Nz
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
|
||||
};
|
||||
|
||||
if (!m_depthBuffer.Create(m_device, imageCreateInfo))
|
||||
if (!m_depthBuffer.Create(*m_device, imageCreateInfo))
|
||||
{
|
||||
NazaraError("Failed to create depth buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
VkMemoryRequirements memoryReq = m_depthBuffer.GetMemoryRequirements();
|
||||
if (!m_depthBufferMemory.Create(m_device, memoryReq.size, memoryReq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
|
||||
if (!m_depthBufferMemory.Create(*m_device, memoryReq.size, memoryReq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
|
||||
{
|
||||
NazaraError("Failed to allocate depth buffer memory");
|
||||
return false;
|
||||
@@ -236,7 +235,7 @@ namespace Nz
|
||||
}
|
||||
};
|
||||
|
||||
if (!m_depthBufferView.Create(m_device, imageViewCreateInfo))
|
||||
if (!m_depthBufferView.Create(*m_device, imageViewCreateInfo))
|
||||
{
|
||||
NazaraError("Failed to create depth buffer view");
|
||||
return false;
|
||||
@@ -330,7 +329,7 @@ namespace Nz
|
||||
dependencies.data() // const VkSubpassDependency* pDependencies;
|
||||
};
|
||||
|
||||
return m_renderPass.Create(m_device, createInfo);
|
||||
return m_renderPass.Create(*m_device, createInfo);
|
||||
}
|
||||
|
||||
bool VkRenderWindow::SetupSwapchain(Vk::Surface& surface, const Vector2ui& size)
|
||||
@@ -395,7 +394,7 @@ namespace Nz
|
||||
0
|
||||
};
|
||||
|
||||
if (!m_swapchain.Create(m_device, swapchainInfo))
|
||||
if (!m_swapchain.Create(*m_device, swapchainInfo))
|
||||
{
|
||||
NazaraError("Failed to create swapchain");
|
||||
return false;
|
||||
|
||||
@@ -444,13 +444,7 @@ namespace Nz
|
||||
{
|
||||
for (auto it = s_devices.begin(); it != s_devices.end();)
|
||||
{
|
||||
auto devicePtr = it->lock();
|
||||
if (!devicePtr)
|
||||
{
|
||||
it = s_devices.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& devicePtr = *it;
|
||||
if (devicePtr->GetPhysicalDevice() == gpu)
|
||||
return devicePtr;
|
||||
}
|
||||
@@ -463,13 +457,7 @@ namespace Nz
|
||||
// First, try to find a device compatible with that surface
|
||||
for (auto it = s_devices.begin(); it != s_devices.end();)
|
||||
{
|
||||
auto devicePtr = it->lock();
|
||||
if (!devicePtr)
|
||||
{
|
||||
it = s_devices.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& devicePtr = *it;
|
||||
if (devicePtr->GetPhysicalDevice() == gpu)
|
||||
{
|
||||
const std::vector<Vk::Device::QueueFamilyInfo>& queueFamilyInfo = devicePtr->GetEnabledQueues();
|
||||
@@ -511,7 +499,7 @@ namespace Nz
|
||||
Vk::Loader::Uninitialize();
|
||||
}
|
||||
|
||||
std::vector<std::weak_ptr<VulkanDevice>> Vulkan::s_devices;
|
||||
std::vector<std::shared_ptr<VulkanDevice>> Vulkan::s_devices;
|
||||
std::vector<Vk::PhysicalDevice> Vulkan::s_physDevices;
|
||||
Vk::Instance Vulkan::s_instance;
|
||||
ParameterList Vulkan::s_initializationParameters;
|
||||
|
||||
@@ -12,20 +12,20 @@ namespace Nz
|
||||
{
|
||||
VulkanDevice::~VulkanDevice() = default;
|
||||
|
||||
std::unique_ptr<AbstractBuffer> VulkanDevice::InstantiateBuffer(Buffer* parent, BufferType type)
|
||||
std::unique_ptr<AbstractBuffer> VulkanDevice::InstantiateBuffer(BufferType type)
|
||||
{
|
||||
return std::make_unique<VulkanBuffer>(shared_from_this(), parent, type);
|
||||
return std::make_unique<VulkanBuffer>(*this, type);
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderPipeline> VulkanDevice::InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo)
|
||||
{
|
||||
return std::make_unique<VulkanRenderPipeline>(shared_from_this(), std::move(pipelineInfo));
|
||||
return std::make_unique<VulkanRenderPipeline>(*this, std::move(pipelineInfo));
|
||||
}
|
||||
|
||||
std::shared_ptr<RenderPipelineLayout> VulkanDevice::InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo)
|
||||
{
|
||||
auto pipelineLayout = std::make_shared<VulkanRenderPipelineLayout>();
|
||||
if (!pipelineLayout->Create(shared_from_this(), std::move(pipelineLayoutInfo)))
|
||||
if (!pipelineLayout->Create(*this, std::move(pipelineLayoutInfo)))
|
||||
return {};
|
||||
|
||||
return pipelineLayout;
|
||||
@@ -34,7 +34,7 @@ namespace Nz
|
||||
std::shared_ptr<ShaderStageImpl> VulkanDevice::InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
||||
{
|
||||
auto stage = std::make_shared<VulkanShaderStage>();
|
||||
if (!stage->Create(shared_from_this(), type, lang, source, sourceSize))
|
||||
if (!stage->Create(*this, type, lang, source, sourceSize))
|
||||
return {};
|
||||
|
||||
return stage;
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
VulkanRenderPipeline::VulkanRenderPipeline(Vk::DeviceHandle device, RenderPipelineInfo pipelineInfo) :
|
||||
m_device(std::move(device)),
|
||||
VulkanRenderPipeline::VulkanRenderPipeline(Vk::Device& device, RenderPipelineInfo pipelineInfo) :
|
||||
m_device(&device),
|
||||
m_pipelineInfo(std::move(pipelineInfo))
|
||||
{
|
||||
m_pipelineCreateInfo = BuildCreateInfo(m_pipelineInfo);
|
||||
@@ -29,7 +29,7 @@ namespace Nz
|
||||
pipelineCreateInfo.renderPass = renderPass;
|
||||
|
||||
Vk::Pipeline newPipeline;
|
||||
if (!newPipeline.CreateGraphics(m_device, pipelineCreateInfo))
|
||||
if (!newPipeline.CreateGraphics(*m_device, pipelineCreateInfo))
|
||||
return VK_NULL_HANDLE;
|
||||
|
||||
auto it = m_pipelines.emplace(renderPass, std::move(newPipeline)).first;
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
bool VulkanRenderPipelineLayout::Create(Vk::DeviceHandle device, RenderPipelineLayoutInfo layoutInfo)
|
||||
bool VulkanRenderPipelineLayout::Create(Vk::Device& device, RenderPipelineLayoutInfo layoutInfo)
|
||||
{
|
||||
m_device = std::move(device);
|
||||
m_device = &device;
|
||||
m_layoutInfo = std::move(layoutInfo);
|
||||
|
||||
StackVector<VkDescriptorSetLayoutBinding> layoutBindings = NazaraStackVector(VkDescriptorSetLayoutBinding, m_layoutInfo.bindings.size());
|
||||
@@ -28,10 +28,10 @@ namespace Nz
|
||||
layoutBinding.stageFlags = ToVulkan(bindingInfo.shaderStageFlags);
|
||||
}
|
||||
|
||||
if (!m_descriptorSetLayout.Create(m_device, layoutBindings.size(), layoutBindings.data()))
|
||||
if (!m_descriptorSetLayout.Create(*m_device, UInt32(layoutBindings.size()), layoutBindings.data()))
|
||||
return false;
|
||||
|
||||
if (!m_pipelineLayout.Create(m_device, m_descriptorSetLayout))
|
||||
if (!m_pipelineLayout.Create(*m_device, m_descriptorSetLayout))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Nz
|
||||
|
||||
for (const Vk::PhysicalDevice& physDevice : m_physDevices)
|
||||
{
|
||||
RenderDeviceInfo device;
|
||||
RenderDeviceInfo& device = devices.emplace_back();
|
||||
device.name = physDevice.properties.deviceName;
|
||||
|
||||
switch (physDevice.properties.deviceType)
|
||||
@@ -100,8 +100,6 @@ namespace Nz
|
||||
device.type = RenderDeviceType::Unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
devices.emplace_back(std::move(device));
|
||||
}
|
||||
|
||||
return devices;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
bool VulkanShaderStage::Create(const Vk::DeviceHandle& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
||||
bool VulkanShaderStage::Create(Vk::Device& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
||||
{
|
||||
if (lang != ShaderLanguage::SpirV)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/VulkanRenderer/Wrapper/Device.hpp>
|
||||
#include <Nazara/Core/CallOnExit.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/VulkanRenderer/Wrapper/Queue.hpp>
|
||||
@@ -12,6 +13,28 @@ namespace Nz
|
||||
{
|
||||
namespace Vk
|
||||
{
|
||||
Device::Device(Instance& instance) :
|
||||
m_instance(instance),
|
||||
m_physicalDevice(nullptr),
|
||||
m_device(VK_NULL_HANDLE)
|
||||
{
|
||||
}
|
||||
|
||||
Device::~Device()
|
||||
{
|
||||
if (m_device != VK_NULL_HANDLE)
|
||||
WaitAndDestroyDevice();
|
||||
}
|
||||
|
||||
void Device::Destroy()
|
||||
{
|
||||
if (m_device != VK_NULL_HANDLE)
|
||||
{
|
||||
WaitAndDestroyDevice();
|
||||
ResetPointers();
|
||||
}
|
||||
}
|
||||
|
||||
bool Device::Create(const Vk::PhysicalDevice& deviceInfo, const VkDeviceCreateInfo& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateDevice(deviceInfo.device, &createInfo, allocator, &m_device);
|
||||
@@ -21,6 +44,8 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
CallOnExit destroyOnFailure([this] { Destroy(); });
|
||||
|
||||
m_physicalDevice = &deviceInfo;
|
||||
|
||||
// Store the allocator to access them when needed
|
||||
@@ -53,7 +78,7 @@ namespace Nz
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
NazaraError(String("Failed to query device function: ") + e.what());
|
||||
NazaraError(std::string("Failed to query device function: ") + e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -88,6 +113,8 @@ namespace Nz
|
||||
for (const QueueFamilyInfo& familyInfo : m_enabledQueuesInfos)
|
||||
m_queuesByFamily[familyInfo.familyIndex] = &familyInfo.queues;
|
||||
|
||||
destroyOnFailure.Reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -96,8 +123,37 @@ namespace Nz
|
||||
VkQueue queue;
|
||||
vkGetDeviceQueue(m_device, queueFamilyIndex, queueIndex, &queue);
|
||||
|
||||
return Queue(shared_from_this(), queue);
|
||||
return Queue(*this, queue);
|
||||
}
|
||||
|
||||
void Device::WaitAndDestroyDevice()
|
||||
{
|
||||
assert(m_device != VK_NULL_HANDLE);
|
||||
|
||||
if (vkDeviceWaitIdle)
|
||||
vkDeviceWaitIdle(m_device);
|
||||
|
||||
m_internalData.reset();
|
||||
|
||||
if (vkDestroyDevice)
|
||||
vkDestroyDevice(m_device, (m_allocator.pfnAllocation) ? &m_allocator : nullptr);
|
||||
}
|
||||
|
||||
void Device::ResetPointers()
|
||||
{
|
||||
m_device = VK_NULL_HANDLE;
|
||||
m_physicalDevice = nullptr;
|
||||
|
||||
// Reset functions pointers
|
||||
#define NAZARA_VULKANRENDERER_DEVICE_EXT_BEGIN(ext)
|
||||
#define NAZARA_VULKANRENDERER_DEVICE_EXT_END()
|
||||
#define NAZARA_VULKANRENDERER_DEVICE_FUNCTION(func) func = nullptr;
|
||||
|
||||
#include <Nazara/VulkanRenderer/Wrapper/DeviceFunctions.hpp>
|
||||
|
||||
#undef NAZARA_VULKANRENDERER_DEVICE_EXT_BEGIN
|
||||
#undef NAZARA_VULKANRENDERER_DEVICE_EXT_END
|
||||
#undef NAZARA_VULKANRENDERER_DEVICE_FUNCTION
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,5 +103,20 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
void Instance::ResetPointers()
|
||||
{
|
||||
assert(m_instance != VK_NULL_HANDLE);
|
||||
m_instance = VK_NULL_HANDLE;
|
||||
|
||||
#define NAZARA_VULKANRENDERER_INSTANCE_EXT_BEGIN(ext)
|
||||
#define NAZARA_VULKANRENDERER_INSTANCE_EXT_END()
|
||||
#define NAZARA_VULKANRENDERER_INSTANCE_FUNCTION(func) func = nullptr;
|
||||
|
||||
#include <Nazara/VulkanRenderer/Wrapper/InstanceFunctions.hpp>
|
||||
|
||||
#undef NAZARA_VULKANRENDERER_INSTANCE_EXT_BEGIN
|
||||
#undef NAZARA_VULKANRENDERER_INSTANCE_EXT_END
|
||||
#undef NAZARA_VULKANRENDERER_INSTANCE_FUNCTION
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user