base application class

This commit is contained in:
PancakeTAS 2025-07-01 09:43:56 +02:00
parent e9bee45a36
commit b4e00d2d65
No known key found for this signature in database
3 changed files with 97 additions and 1 deletions

45
include/application.hpp Normal file
View file

@ -0,0 +1,45 @@
#ifndef APPLICATION_HPP
#define APPLICATION_HPP
#include <vulkan/vulkan_core.h>
///
/// 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

9
src/application.cpp Normal file
View file

@ -0,0 +1,9 @@
#include "application.hpp"
#include <stdexcept>
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");
}

View file

@ -2,14 +2,18 @@
#include "vulkan/funcs.hpp"
#include "loader/dl.hpp"
#include "loader/vk.hpp"
#include "application.hpp"
#include "log.hpp"
#include <vulkan/vulkan_core.h>
#include <lsfg.hpp>
#include <optional>
using namespace Vulkan;
namespace {
bool initialized{false};
std::optional<Application> 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<uint32_t>(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<void*>(myvkCreateInstance));
Loader::VK::registerSymbol("vkCreateDevice",
reinterpret_cast<void*>(myvkCreateDevice));
Loader::VK::registerSymbol("vkDestroyDevice",
reinterpret_cast<void*>(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<void*>(myvkCreateInstance));
vk1.defineSymbol("vkCreateDevice",
reinterpret_cast<void*>(myvkCreateDevice));
vk1.defineSymbol("vkDestroyDevice",
reinterpret_cast<void*>(myvkDestroyDevice));
Loader::DL::registerFile(vk1);
// register hooks to dynamic loader under libvulkan.so
@ -62,5 +102,7 @@ void Hooks::initialize() {
reinterpret_cast<void*>(myvkCreateInstance));
vk2.defineSymbol("vkCreateDevice",
reinterpret_cast<void*>(myvkCreateDevice));
vk2.defineSymbol("vkDestroyDevice",
reinterpret_cast<void*>(myvkDestroyDevice));
Loader::DL::registerFile(vk2);
}