Vulkan: Add CreateDevice/SelectDevice functions
Former-commit-id: bb15b0f93fbc5a21c83178f13738976159044d9a [formerly 98145969e963560d9677ad24683189847511b5e6] Former-commit-id: 90348ef452c507387377c609bbb238d735342973
This commit is contained in:
parent
26e2f57c35
commit
a91085550d
|
|
@ -11,7 +11,9 @@
|
||||||
#include <Nazara/Core/Initializer.hpp>
|
#include <Nazara/Core/Initializer.hpp>
|
||||||
#include <Nazara/Core/ParameterList.hpp>
|
#include <Nazara/Core/ParameterList.hpp>
|
||||||
#include <Nazara/Vulkan/Config.hpp>
|
#include <Nazara/Vulkan/Config.hpp>
|
||||||
|
#include <Nazara/Vulkan/VkDevice.hpp>
|
||||||
#include <Nazara/Vulkan/VkInstance.hpp>
|
#include <Nazara/Vulkan/VkInstance.hpp>
|
||||||
|
#include <Nazara/Vulkan/VkSurface.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
|
@ -21,17 +23,22 @@ namespace Nz
|
||||||
Vulkan() = delete;
|
Vulkan() = delete;
|
||||||
~Vulkan() = delete;
|
~Vulkan() = delete;
|
||||||
|
|
||||||
|
static Vk::Device& CreateDevice(VkPhysicalDevice gpu, const Vk::Surface& surface, UInt32* presentableFamilyQueue);
|
||||||
|
|
||||||
static Vk::Instance& GetInstance();
|
static Vk::Instance& GetInstance();
|
||||||
|
|
||||||
static bool Initialize();
|
static bool Initialize();
|
||||||
|
|
||||||
static bool IsInitialized();
|
static bool IsInitialized();
|
||||||
|
|
||||||
|
static Vk::Device& SelectDevice(VkPhysicalDevice gpu, const Vk::Surface& surface, UInt32* presentableFamilyQueue);
|
||||||
|
|
||||||
static void SetParameters(const ParameterList& parameters);
|
static void SetParameters(const ParameterList& parameters);
|
||||||
|
|
||||||
static void Uninitialize();
|
static void Uninitialize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static std::list<Vk::Device> s_devices;
|
||||||
static Vk::Instance s_instance;
|
static Vk::Instance s_instance;
|
||||||
static ParameterList s_initializationParameters;
|
static ParameterList s_initializationParameters;
|
||||||
static unsigned int s_moduleReferenceCounter;
|
static unsigned int s_moduleReferenceCounter;
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,11 @@
|
||||||
#include <Nazara/Vulkan/Vulkan.hpp>
|
#include <Nazara/Vulkan/Vulkan.hpp>
|
||||||
#include <Nazara/Core/CallOnExit.hpp>
|
#include <Nazara/Core/CallOnExit.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
|
#include <Nazara/Core/ErrorFlags.hpp>
|
||||||
#include <Nazara/Core/Log.hpp>
|
#include <Nazara/Core/Log.hpp>
|
||||||
#include <Nazara/Utility/Utility.hpp>
|
#include <Nazara/Utility/Utility.hpp>
|
||||||
#include <Nazara/Vulkan/Config.hpp>
|
#include <Nazara/Vulkan/Config.hpp>
|
||||||
|
#include <array>
|
||||||
#include <Nazara/Vulkan/Debug.hpp>
|
#include <Nazara/Vulkan/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
|
|
@ -156,6 +158,127 @@ namespace Nz
|
||||||
return s_moduleReferenceCounter != 0;
|
return s_moduleReferenceCounter != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vk::Device& Vulkan::CreateDevice(VkPhysicalDevice gpu, const Vk::Surface& surface, UInt32* presentableFamilyQueue)
|
||||||
|
{
|
||||||
|
Nz::ErrorFlags errFlags(ErrorFlag_ThrowException, true);
|
||||||
|
|
||||||
|
std::vector<VkQueueFamilyProperties> queueFamilies;
|
||||||
|
s_instance.GetPhysicalDeviceQueueFamilyProperties(gpu, &queueFamilies);
|
||||||
|
|
||||||
|
// Find a queue that supports graphics operations
|
||||||
|
UInt32 graphicsQueueNodeIndex = UINT32_MAX;
|
||||||
|
UInt32 presentQueueNodeIndex = UINT32_MAX;
|
||||||
|
UInt32 transfertQueueNodeFamily = UINT32_MAX;
|
||||||
|
for (UInt32 i = 0; i < queueFamilies.size(); i++)
|
||||||
|
{
|
||||||
|
bool supportPresentation = false;
|
||||||
|
if (!surface.GetSupportPresentation(gpu, i, &supportPresentation))
|
||||||
|
NazaraWarning("Failed to get presentation support of queue family #" + String::Number(i));
|
||||||
|
|
||||||
|
if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||||
|
{
|
||||||
|
if (graphicsQueueNodeIndex == UINT32_MAX)
|
||||||
|
graphicsQueueNodeIndex = i;
|
||||||
|
|
||||||
|
if (supportPresentation)
|
||||||
|
{
|
||||||
|
graphicsQueueNodeIndex = i;
|
||||||
|
presentQueueNodeIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (supportPresentation)
|
||||||
|
presentQueueNodeIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UInt32 i = 0; i < queueFamilies.size(); i++)
|
||||||
|
{
|
||||||
|
if (queueFamilies[i].queueFlags & VK_QUEUE_TRANSFER_BIT)
|
||||||
|
{
|
||||||
|
transfertQueueNodeFamily = i;
|
||||||
|
if (transfertQueueNodeFamily != graphicsQueueNodeIndex)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<UInt32, 3> usedQueueFamilies = {graphicsQueueNodeIndex, presentQueueNodeIndex, transfertQueueNodeFamily};
|
||||||
|
float priority = 1.f;
|
||||||
|
|
||||||
|
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
|
||||||
|
for (UInt32 queueFamily : usedQueueFamilies)
|
||||||
|
{
|
||||||
|
VkDeviceQueueCreateInfo createInfo = {
|
||||||
|
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
queueFamily,
|
||||||
|
1,
|
||||||
|
&priority
|
||||||
|
};
|
||||||
|
|
||||||
|
queueCreateInfos.emplace_back(createInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<const char*, 1> enabledExtensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
|
||||||
|
std::array<const char*, 0> enabledLayers;
|
||||||
|
|
||||||
|
VkDeviceCreateInfo createInfo = {
|
||||||
|
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
UInt32(queueCreateInfos.size()),
|
||||||
|
queueCreateInfos.data(),
|
||||||
|
UInt32(enabledLayers.size()),
|
||||||
|
enabledLayers.data(),
|
||||||
|
UInt32(enabledLayers.size()),
|
||||||
|
enabledLayers.data(),
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
///TODO: First create then move
|
||||||
|
s_devices.emplace_back(s_instance);
|
||||||
|
|
||||||
|
Vk::Device& device = s_devices.back();
|
||||||
|
device.Create(gpu, createInfo);
|
||||||
|
|
||||||
|
*presentableFamilyQueue = presentQueueNodeIndex;
|
||||||
|
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vk::Device& Vulkan::SelectDevice(VkPhysicalDevice gpu, const Vk::Surface& surface, UInt32* presentableFamilyQueue)
|
||||||
|
{
|
||||||
|
// First, try to find a device compatible with that surface
|
||||||
|
for (Vk::Device& device : s_devices)
|
||||||
|
{
|
||||||
|
if (device.GetPhysicalDevice() == gpu)
|
||||||
|
{
|
||||||
|
const std::vector<Vk::Device::QueueFamilyInfo>& queueFamilyInfo = device.GetEnabledQueues();
|
||||||
|
UInt32 presentableQueueFamilyIndex = UINT32_MAX;
|
||||||
|
for (Vk::Device::QueueFamilyInfo queueInfo : queueFamilyInfo)
|
||||||
|
{
|
||||||
|
bool supported = false;
|
||||||
|
if (surface.GetSupportPresentation(gpu, queueInfo.familyIndex, &supported) && supported)
|
||||||
|
{
|
||||||
|
if (presentableQueueFamilyIndex == UINT32_MAX || queueInfo.flags & VK_QUEUE_GRAPHICS_BIT)
|
||||||
|
{
|
||||||
|
presentableQueueFamilyIndex = queueInfo.familyIndex;
|
||||||
|
if (queueInfo.flags & VK_QUEUE_GRAPHICS_BIT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (presentableQueueFamilyIndex != UINT32_MAX)
|
||||||
|
*presentableFamilyQueue = presentableQueueFamilyIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No device had support for that surface, create one
|
||||||
|
return CreateDevice(gpu, surface, presentableFamilyQueue);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Vulkan::SetParameters(const ParameterList& parameters)
|
void Vulkan::SetParameters(const ParameterList& parameters)
|
||||||
{
|
{
|
||||||
s_initializationParameters = parameters;
|
s_initializationParameters = parameters;
|
||||||
|
|
@ -185,6 +308,7 @@ namespace Nz
|
||||||
Utility::Uninitialize();
|
Utility::Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::list<Vk::Device> Vulkan::s_devices;
|
||||||
Vk::Instance Vulkan::s_instance;
|
Vk::Instance Vulkan::s_instance;
|
||||||
ParameterList Vulkan::s_initializationParameters;
|
ParameterList Vulkan::s_initializationParameters;
|
||||||
unsigned int Vulkan::s_moduleReferenceCounter = 0;
|
unsigned int Vulkan::s_moduleReferenceCounter = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue