diff --git a/openVulkanoCpp/Vulkan/Context.cpp b/openVulkanoCpp/Vulkan/Context.cpp index 21ff1fc..0397eee 100644 --- a/openVulkanoCpp/Vulkan/Context.cpp +++ b/openVulkanoCpp/Vulkan/Context.cpp @@ -29,8 +29,8 @@ namespace openVulkanoCpp::Vulkan CreateDevice(); - swapChain.Init(device, surface, window); - swapChainRenderPass.Init(device, &swapChain); + swapChain.Init(device.get(), surface, window); + swapChainRenderPass.Init(device.get(), &swapChain); pipeline.Init(device->device); @@ -75,10 +75,11 @@ namespace openVulkanoCpp::Vulkan void Context::CreateDevice() { + const std::vector neededExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; deviceManager.Init(instance); - device = deviceManager.GetCompatibleDevice({ VK_KHR_SWAPCHAIN_EXTENSION_NAME }); - device->PrepareDevice({ VK_KHR_SWAPCHAIN_EXTENSION_NAME }, surface); + device = deviceManager.GetCompatibleDevice(neededExtensions); + device->PrepareDevice(neededExtensions, surface); dynamicDispatch.init(instance, &vkGetInstanceProcAddr, device->device, &vkGetDeviceProcAddr); - Logger::RENDER->info("Found device: {0}", device->GetDeviceName());; + Logger::RENDER->info("Found device: {0}", device->GetDeviceName()); } } \ No newline at end of file diff --git a/openVulkanoCpp/Vulkan/Context.hpp b/openVulkanoCpp/Vulkan/Context.hpp index 8569f1b..e47a0de 100644 --- a/openVulkanoCpp/Vulkan/Context.hpp +++ b/openVulkanoCpp/Vulkan/Context.hpp @@ -30,7 +30,7 @@ namespace openVulkanoCpp vk::Instance instance; // Vulkan instance vk::DispatchLoaderDynamic dynamicDispatch; // for access to features not available in statically linked Vulkan lib vk::SurfaceKHR surface; // Vulkan surface to display framebuffer on - Device* device = nullptr; + std::shared_ptr device; SwapChain swapChain; RenderPass swapChainRenderPass; IVulkanWindow* window = nullptr; diff --git a/openVulkanoCpp/Vulkan/Device.cpp b/openVulkanoCpp/Vulkan/Device.cpp index c342a2a..3203fe4 100644 --- a/openVulkanoCpp/Vulkan/Device.cpp +++ b/openVulkanoCpp/Vulkan/Device.cpp @@ -126,7 +126,7 @@ namespace openVulkanoCpp::Vulkan queueFamilyProperties = physicalDevice.getQueueFamilyProperties(); properties = physicalDevice.getProperties(); features = physicalDevice.getFeatures(); - for (auto& ext : physicalDevice.enumerateDeviceExtensionProperties()) { supportedExtensions.insert(ext.extensionName); } + for (auto& ext : physicalDevice.enumerateDeviceExtensionProperties()) { supportedExtensions.insert(ext.extensionName.data()); } // Query device memory properties memoryProperties = physicalDevice.getMemoryProperties(); diff --git a/openVulkanoCpp/Vulkan/Device.hpp b/openVulkanoCpp/Vulkan/Device.hpp index 9159a14..47b7e8d 100644 --- a/openVulkanoCpp/Vulkan/Device.hpp +++ b/openVulkanoCpp/Vulkan/Device.hpp @@ -47,7 +47,7 @@ namespace openVulkanoCpp [[nodiscard]] std::string GetDeviceName() const { - return properties.deviceName; + return properties.deviceName.data(); } void PrepareDevice(const vk::ArrayProxy& requestedExtensions, const vk::SurfaceKHR& surface); @@ -75,7 +75,7 @@ namespace openVulkanoCpp void ExecuteNow(const std::function& function) const; - vk::ShaderModule CreateShaderModule(const std::string& filename) const; + [[nodiscard]] vk::ShaderModule CreateShaderModule(const std::string& filename) const; vk::ShaderModule CreateShaderModule(vk::ShaderModuleCreateInfo& createInfo) const; diff --git a/openVulkanoCpp/Vulkan/DeviceManager.cpp b/openVulkanoCpp/Vulkan/DeviceManager.cpp new file mode 100644 index 0000000..f3313da --- /dev/null +++ b/openVulkanoCpp/Vulkan/DeviceManager.cpp @@ -0,0 +1,58 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "DeviceManager.hpp" +#include "Device.hpp" +#include + +namespace openVulkanoCpp::Vulkan +{ + void DeviceManager::Init(const vk::Instance& instance) + { + if (!devices.empty()) Close(); + for (auto& physicalDevice: instance.enumeratePhysicalDevices()) + { + devices.push_back(std::make_shared(physicalDevice)); + } + } + + std::shared_ptr DeviceManager::GetCompatibleDevice(const vk::ArrayProxy& deviceExtensions) + { + for (const auto& device: devices) + { + if (device->IsExtensionAvailable(deviceExtensions)) return device; + } + throw std::runtime_error("No device with required extensions found!\n" + ProduceMissingDeviceCompatibilityReport(deviceExtensions)); + } + + std::string DeviceManager::ProduceMissingDeviceCompatibilityReport(const vk::ArrayProxy& deviceExtensions) + { + std::stringstream ss; + ss << "Requested Extensions: ["; + bool first = true; + for (const std::string& ext : deviceExtensions) + { + ss << ' ' << ext; + if (first) first = false; + else ss << ','; + } + ss << " ]\nAvailable Devices: [\n"; + for (const auto& device: devices) + { + ss << '\t' << device->GetDeviceName() << ": ["; + first = true; + for (const std::string& ext : device->GetExtensions()) + { + ss << ' ' << ext; + if (first) first = false; + else ss << ','; + } + ss << " ]\n"; + } + ss << ']'; + return ss.str(); + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Vulkan/DeviceManager.hpp b/openVulkanoCpp/Vulkan/DeviceManager.hpp index 2532dfc..f60e906 100644 --- a/openVulkanoCpp/Vulkan/DeviceManager.hpp +++ b/openVulkanoCpp/Vulkan/DeviceManager.hpp @@ -1,44 +1,42 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once -#include + +#include #include -#include "Base/ICloseable.hpp" -#include "Device.hpp" +#include -namespace openVulkanoCpp +namespace openVulkanoCpp::Vulkan { - namespace Vulkan + class Device; + + class DeviceManager final { + std::vector> devices; - class DeviceManager : virtual public ICloseable + public: + DeviceManager() = default; + + DeviceManager(const vk::Instance& instance) { - std::vector devices; - public: - void Init(const vk::Instance& instance) - { - devices = std::vector(); - for (auto& physicalDevice : instance.enumeratePhysicalDevices()) - { - devices.emplace_back(physicalDevice); - } - } + Init(instance); + } - Device* GetCompatibleDevice(const std::vector& deviceExtensions) - { - for (auto& device : devices) - { - if (device.IsExtensionAvailable(deviceExtensions)) return &device; - } - throw std::runtime_error("No device with required extensions found!"); - } + ~DeviceManager() = default; - void Close() override - { - for (auto& device : devices) - { - device.Close(); - } - devices.clear(); - } - }; - } + void Init(const vk::Instance& instance); + + std::shared_ptr GetCompatibleDevice(const vk::ArrayProxy& deviceExtensions); + + std::string ProduceMissingDeviceCompatibilityReport(const vk::ArrayProxy& deviceExtensions); + + void Close() + { + devices.clear(); + } + }; }