diff --git a/include/Nazara/VulkanRenderer/VkRenderWindow.hpp b/include/Nazara/VulkanRenderer/VkRenderWindow.hpp index 2914dcacb..d58dbe883 100644 --- a/include/Nazara/VulkanRenderer/VkRenderWindow.hpp +++ b/include/Nazara/VulkanRenderer/VkRenderWindow.hpp @@ -58,13 +58,12 @@ namespace Nz private: bool SetupDepthBuffer(const Vector2ui& size); bool SetupRenderPass(); - bool SetupSwapchain(Vk::Surface& surface, const Vector2ui& size); + bool SetupSwapchain(const Vk::PhysicalDevice& deviceInfo, Vk::Surface& surface, const Vector2ui& size); Clock m_clock; VkColorSpaceKHR m_colorSpace; VkFormat m_colorFormat; VkFormat m_depthStencilFormat; - VkPhysicalDevice m_physicalDevice; std::shared_ptr m_device; std::vector m_frameBuffers; Vk::DeviceMemory m_depthBufferMemory; diff --git a/include/Nazara/VulkanRenderer/Vulkan.hpp b/include/Nazara/VulkanRenderer/Vulkan.hpp index ef88e3d10..bffff2e1a 100644 --- a/include/Nazara/VulkanRenderer/Vulkan.hpp +++ b/include/Nazara/VulkanRenderer/Vulkan.hpp @@ -35,9 +35,9 @@ namespace Nz Vulkan() = delete; ~Vulkan() = delete; - static std::shared_ptr CreateDevice(VkPhysicalDevice gpu); - static std::shared_ptr CreateDevice(VkPhysicalDevice gpu, const Vk::Surface& surface, UInt32* presentableFamilyQueue); - static std::shared_ptr CreateDevice(VkPhysicalDevice gpu, const QueueFamily* queueFamilies, std::size_t queueFamilyCount); + static std::shared_ptr CreateDevice(const Vk::PhysicalDevice& deviceInfo); + static std::shared_ptr CreateDevice(const Vk::PhysicalDevice& deviceInfo, const Vk::Surface& surface, UInt32* presentableFamilyQueue); + static std::shared_ptr CreateDevice(const Vk::PhysicalDevice& deviceInfo, const QueueFamily* queueFamilies, std::size_t queueFamilyCount); static Vk::Instance& GetInstance(); @@ -48,8 +48,8 @@ namespace Nz static bool IsInitialized(); - static std::shared_ptr SelectDevice(VkPhysicalDevice gpu); - static std::shared_ptr SelectDevice(VkPhysicalDevice gpu, const Vk::Surface& surface, UInt32* presentableFamilyQueue); + static std::shared_ptr SelectDevice(const Vk::PhysicalDevice& deviceInfo); + static std::shared_ptr SelectDevice(const Vk::PhysicalDevice& deviceInfo, const Vk::Surface& surface, UInt32* presentableFamilyQueue); static void Uninitialize(); diff --git a/include/Nazara/VulkanRenderer/Wrapper/Device.inl b/include/Nazara/VulkanRenderer/Wrapper/Device.inl index 1d44e193d..81ae1f4b3 100644 --- a/include/Nazara/VulkanRenderer/Wrapper/Device.inl +++ b/include/Nazara/VulkanRenderer/Wrapper/Device.inl @@ -41,7 +41,7 @@ namespace Nz inline VkPhysicalDevice Device::GetPhysicalDevice() const { - return m_physicalDevice->device; + return m_physicalDevice->physDevice; } inline const Vk::PhysicalDevice& Device::GetPhysicalDeviceInfo() const diff --git a/include/Nazara/VulkanRenderer/Wrapper/PhysicalDevice.hpp b/include/Nazara/VulkanRenderer/Wrapper/PhysicalDevice.hpp index 266d1d877..3e58e1f16 100644 --- a/include/Nazara/VulkanRenderer/Wrapper/PhysicalDevice.hpp +++ b/include/Nazara/VulkanRenderer/Wrapper/PhysicalDevice.hpp @@ -8,6 +8,7 @@ #define NAZARA_VULKANRENDERER_VKPHYSICALDEVICE_HPP #include +#include #include namespace Nz @@ -16,11 +17,11 @@ namespace Nz { struct PhysicalDevice { - VkPhysicalDevice device; + VkPhysicalDevice physDevice; VkPhysicalDeviceFeatures features; VkPhysicalDeviceMemoryProperties memoryProperties; VkPhysicalDeviceProperties properties; - std::vector queues; + std::vector queueFamilies; }; } } diff --git a/src/Nazara/VulkanRenderer/VkRenderWindow.cpp b/src/Nazara/VulkanRenderer/VkRenderWindow.cpp index f1c367d6e..72588bfd4 100644 --- a/src/Nazara/VulkanRenderer/VkRenderWindow.cpp +++ b/src/Nazara/VulkanRenderer/VkRenderWindow.cpp @@ -16,7 +16,6 @@ namespace Nz { VkRenderWindow::VkRenderWindow() : - m_physicalDevice(nullptr), m_depthStencilFormat(VK_FORMAT_MAX_ENUM) { } @@ -46,11 +45,11 @@ namespace Nz bool VkRenderWindow::Create(RendererImpl* /*renderer*/, RenderSurface* surface, const Vector2ui& size, const RenderWindowParameters& parameters) { - m_physicalDevice = Vulkan::GetPhysicalDevices()[0].device; + const auto& deviceInfo = Vulkan::GetPhysicalDevices()[0]; Vk::Surface& vulkanSurface = static_cast(surface)->GetSurface(); - m_device = Vulkan::SelectDevice(m_physicalDevice, vulkanSurface, &m_presentableFamilyQueue); + m_device = Vulkan::SelectDevice(deviceInfo, vulkanSurface, &m_presentableFamilyQueue); if (!m_device) { NazaraError("Failed to get compatible Vulkan device"); @@ -60,7 +59,7 @@ namespace Nz m_presentQueue = m_device->GetQueue(m_presentableFamilyQueue, 0); std::vector surfaceFormats; - if (!vulkanSurface.GetFormats(m_physicalDevice, &surfaceFormats)) + if (!vulkanSurface.GetFormats(deviceInfo.physDevice, &surfaceFormats)) { NazaraError("Failed to query supported surface formats"); return false; @@ -115,7 +114,7 @@ namespace Nz if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM) { - VkFormatProperties formatProperties = m_device->GetInstance().GetPhysicalDeviceFormatProperties(m_physicalDevice, m_depthStencilFormat); + VkFormatProperties formatProperties = m_device->GetInstance().GetPhysicalDeviceFormatProperties(deviceInfo.physDevice, m_depthStencilFormat); if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) break; //< Found it @@ -124,7 +123,7 @@ namespace Nz } } - if (!SetupSwapchain(vulkanSurface, size)) + if (!SetupSwapchain(deviceInfo, vulkanSurface, size)) { NazaraError("Failed to create swapchain"); return false; @@ -332,10 +331,10 @@ namespace Nz return m_renderPass.Create(*m_device, createInfo); } - bool VkRenderWindow::SetupSwapchain(Vk::Surface& surface, const Vector2ui& size) + bool VkRenderWindow::SetupSwapchain(const Vk::PhysicalDevice& deviceInfo, Vk::Surface& surface, const Vector2ui& size) { VkSurfaceCapabilitiesKHR surfaceCapabilities; - if (!surface.GetCapabilities(m_physicalDevice, &surfaceCapabilities)) + if (!surface.GetCapabilities(deviceInfo.physDevice, &surfaceCapabilities)) { NazaraError("Failed to query surface capabilities"); return false; @@ -355,7 +354,7 @@ namespace Nz extent = surfaceCapabilities.currentExtent; std::vector presentModes; - if (!surface.GetPresentModes(m_physicalDevice, &presentModes)) + if (!surface.GetPresentModes(deviceInfo.physDevice, &presentModes)) { NazaraError("Failed to query supported present modes"); return false; @@ -391,7 +390,7 @@ namespace Nz VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, swapchainPresentMode, VK_TRUE, - 0 + VK_NULL_HANDLE }; if (!m_swapchain.Create(*m_device, swapchainInfo)) diff --git a/src/Nazara/VulkanRenderer/Vulkan.cpp b/src/Nazara/VulkanRenderer/Vulkan.cpp index cb211ad01..d0d6b9da6 100644 --- a/src/Nazara/VulkanRenderer/Vulkan.cpp +++ b/src/Nazara/VulkanRenderer/Vulkan.cpp @@ -29,7 +29,7 @@ namespace Nz { for (const Vk::PhysicalDevice& info : s_physDevices) { - if (info.device == physDevice) + if (info.physDevice == physDevice) return info; } @@ -190,13 +190,13 @@ namespace Nz for (VkPhysicalDevice physDevice : physDevices) { Vk::PhysicalDevice deviceInfo; - if (!s_instance.GetPhysicalDeviceQueueFamilyProperties(physDevice, &deviceInfo.queues)) + if (!s_instance.GetPhysicalDeviceQueueFamilyProperties(physDevice, &deviceInfo.queueFamilies)) { NazaraWarning("Failed to query physical device queue family properties for " + String(deviceInfo.properties.deviceName) + " (0x" + String::Number(deviceInfo.properties.deviceID, 16) + ')'); continue; } - deviceInfo.device = physDevice; + deviceInfo.physDevice = physDevice; deviceInfo.features = s_instance.GetPhysicalDeviceFeatures(physDevice); deviceInfo.memoryProperties = s_instance.GetPhysicalDeviceMemoryProperties(physDevice); @@ -224,29 +224,26 @@ namespace Nz return s_instance.IsValid(); } - std::shared_ptr Vulkan::CreateDevice(VkPhysicalDevice gpu) + std::shared_ptr Vulkan::CreateDevice(const Vk::PhysicalDevice& deviceInfo) { Nz::ErrorFlags errFlags(ErrorFlag_ThrowException, true); - std::vector queueFamilies; - s_instance.GetPhysicalDeviceQueueFamilyProperties(gpu, &queueFamilies); - // Find a queue that supports graphics operations UInt32 graphicsQueueNodeIndex = UINT32_MAX; UInt32 transfertQueueNodeFamily = UINT32_MAX; - for (UInt32 i = 0; i < queueFamilies.size(); i++) + for (UInt32 i = 0; i < deviceInfo.queueFamilies.size(); i++) { - if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) + if (deviceInfo.queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { graphicsQueueNodeIndex = i; break; } } - for (UInt32 i = 0; i < queueFamilies.size(); i++) + for (UInt32 i = 0; i < deviceInfo.queueFamilies.size(); i++) { - if (queueFamilies[i].queueFlags & (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT)) //< Compute and graphics queue implicitly support transfer operations + if (deviceInfo.queueFamilies[i].queueFlags & (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT)) //< Compute and graphics queue implicitly support transfer operations { transfertQueueNodeFamily = i; if (transfertQueueNodeFamily != graphicsQueueNodeIndex) @@ -261,27 +258,24 @@ namespace Nz } }; - return CreateDevice(gpu, queuesFamilies.data(), queuesFamilies.size()); + return CreateDevice(deviceInfo, queuesFamilies.data(), queuesFamilies.size()); } - std::shared_ptr Vulkan::CreateDevice(VkPhysicalDevice gpu, const Vk::Surface& surface, UInt32* presentableFamilyQueue) + std::shared_ptr Vulkan::CreateDevice(const Vk::PhysicalDevice& deviceInfo, const Vk::Surface& surface, UInt32* presentableFamilyQueue) { Nz::ErrorFlags errFlags(ErrorFlag_ThrowException, true); - std::vector queueFamilies; - s_instance.GetPhysicalDeviceQueueFamilyProperties(gpu, &queueFamilies); - // Find a queue that supports graphics operations UInt32 graphicsQueueNodeIndex = UINT32_MAX; UInt32 presentQueueNodeIndex = UINT32_MAX; UInt32 transferQueueNodeFamily = UINT32_MAX; - for (UInt32 i = 0; i < queueFamilies.size(); i++) + for (UInt32 i = 0; i < deviceInfo.queueFamilies.size(); i++) { bool supportPresentation = false; - if (!surface.GetSupportPresentation(gpu, i, &supportPresentation)) + if (!surface.GetSupportPresentation(deviceInfo.physDevice, i, &supportPresentation)) NazaraWarning("Failed to get presentation support of queue family #" + String::Number(i)); - if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) + if (deviceInfo.queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { if (supportPresentation) { @@ -312,10 +306,10 @@ namespace Nz } // Search for a transfer queue (first one being different to the graphics one) - for (UInt32 i = 0; i < queueFamilies.size(); i++) + for (UInt32 i = 0; i < deviceInfo.queueFamilies.size(); i++) { // Transfer bit is not mandatory if compute and graphics bits are set (as they implicitly support transfer) - if (queueFamilies[i].queueFlags & (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT)) + if (deviceInfo.queueFamilies[i].queueFlags & (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT)) { transferQueueNodeFamily = i; if (transferQueueNodeFamily != graphicsQueueNodeIndex) @@ -334,10 +328,10 @@ namespace Nz *presentableFamilyQueue = presentQueueNodeIndex; - return CreateDevice(gpu, queuesFamilies.data(), queuesFamilies.size()); + return CreateDevice(deviceInfo, queuesFamilies.data(), queuesFamilies.size()); } - std::shared_ptr Vulkan::CreateDevice(VkPhysicalDevice gpu, const QueueFamily* queueFamilies, std::size_t queueFamilyCount) + std::shared_ptr Vulkan::CreateDevice(const Vk::PhysicalDevice& deviceInfo, const QueueFamily* queueFamilies, std::size_t queueFamilyCount) { std::vector queueCreateInfos; queueCreateInfos.reserve(queueFamilyCount); @@ -396,8 +390,12 @@ namespace Nz } if (!s_initializationParameters.GetBooleanParameter("VkDeviceInfo_OverrideEnabledExtensions", &bParam) || !bParam) + { + // Swapchain extension is required for rendering enabledExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + } + std::vector additionalExtensions; // Just to keep the String alive if (s_initializationParameters.GetIntegerParameter("VkDeviceInfo_EnabledExtensionCount", &iParam)) { @@ -429,7 +427,7 @@ namespace Nz }; std::shared_ptr device = std::make_shared(s_instance); - if (!device->Create(GetPhysicalDeviceInfo(gpu), createInfo)) + if (!device->Create(deviceInfo, createInfo)) { NazaraError("Failed to create Vulkan Device: " + TranslateVulkanError(device->GetLastErrorCode())); return {}; @@ -440,32 +438,32 @@ namespace Nz return device; } - std::shared_ptr Vulkan::SelectDevice(VkPhysicalDevice gpu) + std::shared_ptr Vulkan::SelectDevice(const Vk::PhysicalDevice& deviceInfo) { for (auto it = s_devices.begin(); it != s_devices.end();) { const auto& devicePtr = *it; - if (devicePtr->GetPhysicalDevice() == gpu) + if (devicePtr->GetPhysicalDevice() == deviceInfo.physDevice) return devicePtr; } - return CreateDevice(gpu); + return CreateDevice(deviceInfo); } - std::shared_ptr Vulkan::SelectDevice(VkPhysicalDevice gpu, const Vk::Surface& surface, UInt32* presentableFamilyQueue) + std::shared_ptr Vulkan::SelectDevice(const Vk::PhysicalDevice& deviceInfo, const Vk::Surface& surface, UInt32* presentableFamilyQueue) { // First, try to find a device compatible with that surface for (auto it = s_devices.begin(); it != s_devices.end();) { const auto& devicePtr = *it; - if (devicePtr->GetPhysicalDevice() == gpu) + if (devicePtr->GetPhysicalDevice() == deviceInfo.physDevice) { const std::vector& queueFamilyInfo = devicePtr->GetEnabledQueues(); UInt32 presentableQueueFamilyIndex = UINT32_MAX; for (const Vk::Device::QueueFamilyInfo& queueInfo : queueFamilyInfo) { bool supported = false; - if (surface.GetSupportPresentation(gpu, queueInfo.familyIndex, &supported) && supported) + if (surface.GetSupportPresentation(deviceInfo.physDevice, queueInfo.familyIndex, &supported) && supported) { if (presentableQueueFamilyIndex == UINT32_MAX || queueInfo.flags & VK_QUEUE_GRAPHICS_BIT) { @@ -487,7 +485,7 @@ namespace Nz } // No device had support for that surface, create one - return CreateDevice(gpu, surface, presentableFamilyQueue); + return CreateDevice(deviceInfo, surface, presentableFamilyQueue); } void Vulkan::Uninitialize() diff --git a/src/Nazara/VulkanRenderer/VulkanRenderer.cpp b/src/Nazara/VulkanRenderer/VulkanRenderer.cpp index bfacf89bc..ee06a5bf9 100644 --- a/src/Nazara/VulkanRenderer/VulkanRenderer.cpp +++ b/src/Nazara/VulkanRenderer/VulkanRenderer.cpp @@ -32,7 +32,7 @@ namespace Nz std::shared_ptr VulkanRenderer::InstanciateRenderDevice(std::size_t deviceIndex) { assert(deviceIndex < m_physDevices.size()); - return Vulkan::SelectDevice(m_physDevices[deviceIndex].device); + return Vulkan::SelectDevice(m_physDevices[deviceIndex]); } bool VulkanRenderer::IsBetterThan(const RendererImpl* other) const diff --git a/src/Nazara/VulkanRenderer/Wrapper/Device.cpp b/src/Nazara/VulkanRenderer/Wrapper/Device.cpp index a795dd7de..4c566fb30 100644 --- a/src/Nazara/VulkanRenderer/Wrapper/Device.cpp +++ b/src/Nazara/VulkanRenderer/Wrapper/Device.cpp @@ -40,7 +40,7 @@ namespace Nz bool Device::Create(const Vk::PhysicalDevice& deviceInfo, const VkDeviceCreateInfo& createInfo, const VkAllocationCallbacks* allocator) { - m_lastErrorCode = m_instance.vkCreateDevice(deviceInfo.device, &createInfo, allocator, &m_device); + m_lastErrorCode = m_instance.vkCreateDevice(deviceInfo.physDevice, &createInfo, allocator, &m_device); if (m_lastErrorCode != VkResult::VK_SUCCESS) { NazaraError("Failed to create Vulkan device"); @@ -99,7 +99,7 @@ namespace Nz if (info.familyIndex > maxFamilyIndex) maxFamilyIndex = info.familyIndex; - const VkQueueFamilyProperties& queueProperties = deviceInfo.queues[info.familyIndex]; + const VkQueueFamilyProperties& queueProperties = deviceInfo.queueFamilies[info.familyIndex]; info.flags = queueProperties.queueFlags; info.minImageTransferGranularity = queueProperties.minImageTransferGranularity; info.timestampValidBits = queueProperties.timestampValidBits;