From b4e00d2d650c01761165e56b22c41ed8bfbd3d4a Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Tue, 1 Jul 2025 09:43:56 +0200 Subject: [PATCH] base application class --- include/application.hpp | 45 +++++++++++++++++++++++++++++++++++++++++ src/application.cpp | 9 +++++++++ src/vulkan/hooks.cpp | 44 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 include/application.hpp create mode 100644 src/application.cpp diff --git a/include/application.hpp b/include/application.hpp new file mode 100644 index 0000000..16f4d0a --- /dev/null +++ b/include/application.hpp @@ -0,0 +1,45 @@ +#ifndef APPLICATION_HPP +#define APPLICATION_HPP + +#include + +/// +/// Main application class, wrapping around the Vulkan device. +/// +class Application { +public: + + /// + /// Create the application. + /// + /// @param device Vulkan device + /// @param physicalDevice Vulkan physical device + /// + /// @throws std::invalid_argument if the device or physicalDevice is null. + /// @throws LSFG::vulkan_error if any Vulkan call fails. + /// + Application(VkDevice device, VkPhysicalDevice physicalDevice); + + /// Get the Vulkan device. + [[nodiscard]] VkDevice getDevice() const { return this->device; } + /// Get the Vulkan physical device. + [[nodiscard]] VkPhysicalDevice getPhysicalDevice() const { return this->physicalDevice; } + + // Non-copyable and non-movable + Application(const Application&) = delete; + Application& operator=(const Application&) = delete; + Application(Application&&) = delete; + Application& operator=(Application&&) = delete; + + /// Destructor, cleans up resources. + ~Application() = default; // no resources to clean up as of right now. +private: + // (non-owned resources) + VkDevice device; + VkPhysicalDevice physicalDevice; + + // (owned resources) + +}; + +#endif // APPLICATION_HPP diff --git a/src/application.cpp b/src/application.cpp new file mode 100644 index 0000000..b22b10c --- /dev/null +++ b/src/application.cpp @@ -0,0 +1,9 @@ +#include "application.hpp" + +#include + +Application::Application(VkDevice device, VkPhysicalDevice physicalDevice) + : device(device), physicalDevice(physicalDevice) { + if (device == VK_NULL_HANDLE || physicalDevice == VK_NULL_HANDLE) + throw std::invalid_argument("Invalid Vulkan device or physical device"); +} diff --git a/src/vulkan/hooks.cpp b/src/vulkan/hooks.cpp index aef658c..e711fca 100644 --- a/src/vulkan/hooks.cpp +++ b/src/vulkan/hooks.cpp @@ -2,14 +2,18 @@ #include "vulkan/funcs.hpp" #include "loader/dl.hpp" #include "loader/vk.hpp" +#include "application.hpp" #include "log.hpp" -#include +#include + +#include using namespace Vulkan; namespace { bool initialized{false}; + std::optional application; VkResult myvkCreateInstance( const VkInstanceCreateInfo* pCreateInfo, @@ -31,9 +35,41 @@ namespace { Funcs::initializeDevice(*pDevice); + // create the main application + if (application.has_value()) { + Log::error("Application already initialized, are you trying to create a second device?"); + exit(EXIT_FAILURE); + } + + try { + application.emplace(*pDevice, physicalDevice); + Log::info("lsfg-vk(hooks): Application created successfully"); + } catch (const LSFG::vulkan_error& e) { + Log::error("Encountered Vulkan error {:x} while creating application: {}", + static_cast(e.error()), e.what()); + exit(EXIT_FAILURE); + } catch (const std::exception& e) { + Log::error("Encountered error while creating application: {}", e.what()); + exit(EXIT_FAILURE); + } + return res; } + void myvkDestroyDevice( + VkDevice device, + const VkAllocationCallbacks* pAllocator) { + // destroy the main application + if (application.has_value()) { + application.reset(); + Log::info("lsfg-vk(hooks): Application destroyed successfully"); + } else { + Log::warn("lsfg-vk(hooks): No application to destroy, continuing"); + } + + Funcs::ovkDestroyDevice(device, pAllocator); + } + } void Hooks::initialize() { @@ -47,6 +83,8 @@ void Hooks::initialize() { reinterpret_cast(myvkCreateInstance)); Loader::VK::registerSymbol("vkCreateDevice", reinterpret_cast(myvkCreateDevice)); + Loader::VK::registerSymbol("vkDestroyDevice", + reinterpret_cast(myvkDestroyDevice)); // register hooks to dynamic loader under libvulkan.so.1 Loader::DL::File vk1("libvulkan.so.1"); @@ -54,6 +92,8 @@ void Hooks::initialize() { reinterpret_cast(myvkCreateInstance)); vk1.defineSymbol("vkCreateDevice", reinterpret_cast(myvkCreateDevice)); + vk1.defineSymbol("vkDestroyDevice", + reinterpret_cast(myvkDestroyDevice)); Loader::DL::registerFile(vk1); // register hooks to dynamic loader under libvulkan.so @@ -62,5 +102,7 @@ void Hooks::initialize() { reinterpret_cast(myvkCreateInstance)); vk2.defineSymbol("vkCreateDevice", reinterpret_cast(myvkCreateDevice)); + vk2.defineSymbol("vkDestroyDevice", + reinterpret_cast(myvkDestroyDevice)); Loader::DL::registerFile(vk2); }