Move to vulkan raii.
Vulkan RAII is new, but it helps manage a multi-device environment without the additional context-tracking.
This commit is contained in:
parent
e9da60c056
commit
cd8ab16ad2
|
|
@ -1,18 +1,15 @@
|
|||
#include <iostream>
|
||||
#include "constants.h"
|
||||
#include "glfw_context.h"
|
||||
#include "window.h"
|
||||
#include <iostream>
|
||||
|
||||
int main(int, char**) {
|
||||
int main(int, char **) {
|
||||
GlfwContext glfw = {};
|
||||
Context context = {"Aster", VERSION};
|
||||
Window window = {"Aster1", &context, { 640, 480 }};
|
||||
|
||||
GlfwContext* glfw = new GlfwContext();
|
||||
Context* context = new Context("Aster", VERSION);
|
||||
Window* window = new Window("Aster1", context, { 640, 480 });
|
||||
|
||||
delete window;
|
||||
delete context;
|
||||
delete glfw;
|
||||
while (window.poll()) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#define GLFW_INCLUDE_VULKAN
|
||||
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
|
||||
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
||||
#define VULKAN_HPP_NO_EXCEPTIONS
|
||||
|
||||
#if defined(NDEBUG)
|
||||
#define USE_OPTICK (0)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "context.h"
|
||||
|
||||
VKAPI_ATTR b32 VKAPI_CALL Context::debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT _message_severity, VkDebugUtilsMessageTypeFlagsEXT _message_type, const VkDebugUtilsMessengerCallbackDataEXT *_callback_data, [[maybe_unused]] void *_user_data) {
|
||||
VKAPI_ATTR b32 VKAPI_CALL Context::debug_callback(const VkDebugUtilsMessageSeverityFlagBitsEXT _message_severity, const VkDebugUtilsMessageTypeFlagsEXT _message_type, const VkDebugUtilsMessengerCallbackDataEXT *_callback_data, [[maybe_unused]] void *_user_data) {
|
||||
using Severity = vk::DebugUtilsMessageSeverityFlagsEXT;
|
||||
using SeverityBits = vk::DebugUtilsMessageSeverityFlagBitsEXT;
|
||||
using MessageType = vk::DebugUtilsMessageTypeFlagsEXT;
|
||||
|
|
@ -29,8 +29,6 @@ VKAPI_ATTR b32 VKAPI_CALL Context::debug_callback(VkDebugUtilsMessageSeverityFla
|
|||
}
|
||||
|
||||
void Context::init(const std::string_view &_app_name, const Version &_app_version) {
|
||||
vk::Result result;
|
||||
|
||||
INFO_IF(enable_validation_layers, "Validation Layers enabled");
|
||||
|
||||
// Creating Instance
|
||||
|
|
@ -67,33 +65,31 @@ void Context::init(const std::string_view &_app_name, const Version &_app_versio
|
|||
const auto vkGetInstanceProcAddr = dl.getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
|
||||
|
||||
tie(result, instance) = vk::createInstance({
|
||||
try {
|
||||
instance = vk::raii::Instance{ raii_context, {
|
||||
.pNext = enable_validation_layers ? &debug_messenger_create_info : nullptr,
|
||||
.pApplicationInfo = &app_info,
|
||||
.enabledLayerCount = enable_validation_layers ? cast<u32>(validation_layers.size()) : 0,
|
||||
.ppEnabledLayerNames = enable_validation_layers ? validation_layers.data() : nullptr,
|
||||
.enabledExtensionCount = cast<u32>(vulkan_extensions.size()),
|
||||
.ppEnabledExtensionNames = vulkan_extensions.data(),
|
||||
});
|
||||
ERROR_IF(failed(result), "Failed to create Vulkan instance with "s + to_string(result))
|
||||
THEN_CRASH(result)
|
||||
ELSE_INFO("Instance Created.");
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
|
||||
} };
|
||||
} catch (const std::exception &err) {
|
||||
ERROR("Failed to create Vulkan instance with "s + err.what());
|
||||
throw err;
|
||||
}
|
||||
INFO("Instance Created.");
|
||||
|
||||
// Debug Messenger
|
||||
if (enable_validation_layers) {
|
||||
tie(result, debug_messenger) = instance.createDebugUtilsMessengerEXT(debug_messenger_create_info);
|
||||
ERROR_IF(failed(result), "Debug Messenger creation failed with "s + to_string(result))
|
||||
ELSE_INFO("Debug Messenger Created.");
|
||||
try {
|
||||
debug_messenger = vk::raii::DebugUtilsMessengerEXT{ instance, debug_messenger_create_info };
|
||||
} catch (const std::exception &err) {
|
||||
ERROR("Debug Messenger creation failed with "s + err.what());
|
||||
throw err;
|
||||
}
|
||||
INFO("Debug Messenger Created.");
|
||||
}
|
||||
}
|
||||
|
||||
Context::~Context() {
|
||||
if (instance) {
|
||||
if (enable_validation_layers && debug_messenger) {
|
||||
instance.destroyDebugUtilsMessengerEXT(debug_messenger);
|
||||
}
|
||||
instance.destroy();
|
||||
INFO("Context destroyed");
|
||||
}
|
||||
}
|
||||
Context::~Context() = default;
|
||||
|
|
|
|||
|
|
@ -73,8 +73,9 @@ public:
|
|||
VK_KHR_MULTIVIEW_EXTENSION_NAME,
|
||||
};
|
||||
|
||||
vk::Instance instance;
|
||||
vk::DebugUtilsMessengerEXT debug_messenger;
|
||||
vk::raii::Context raii_context;
|
||||
vk::raii::Instance instance{ nullptr };
|
||||
vk::raii::DebugUtilsMessengerEXT debug_messenger{ nullptr };
|
||||
|
||||
private:
|
||||
void init(const std::string_view &_app_name, const Version &_app_version);
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@
|
|||
#include <string>
|
||||
|
||||
#define VULKAN_HPP_ASSERT(expr) DEBUG_IF(!(expr), "Vulkan assert failed")
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vk_mem_alloc.h>
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
|
||||
#define CODE_LOC " @ " __FILE__ ":" VULKAN_HPP_STRINGIFY(__LINE__)
|
||||
[[nodiscard]] inline bool failed(const vk::Result _result) {
|
||||
|
|
|
|||
|
|
@ -4,16 +4,13 @@
|
|||
// =============================================
|
||||
|
||||
#include "window.h"
|
||||
#include "logger.h"
|
||||
#include "context.h"
|
||||
#include "glfw_context.h"
|
||||
#include "logger.h"
|
||||
|
||||
Window::Window(const std::string_view& _title, Context* _context, vk::Extent2D _extent, b8 _full_screen)
|
||||
: parent_context{ std::move(_context) }
|
||||
, extent{ _extent }
|
||||
, name{ _title }
|
||||
, full_screen{ _full_screen } {
|
||||
|
||||
Window::Window(const std::string_view &_title, Context *_context, const vk::Extent2D _extent, const bool _full_screen) :
|
||||
extent{ _extent }, name{ _title } {
|
||||
full_screen = _full_screen;
|
||||
monitor = glfwGetPrimaryMonitor();
|
||||
ERROR_IF(monitor == nullptr, "No monitor found");
|
||||
|
||||
|
|
@ -23,8 +20,9 @@ Window::Window(const std::string_view& _title, Context* _context, vk::Extent2D _
|
|||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
glfwWindowHint(GLFW_CENTER_CURSOR, GLFW_TRUE);
|
||||
|
||||
window = glfwCreateWindow(extent.width, extent.height, name.data(), full_screen ? monitor : nullptr, nullptr);
|
||||
ERROR_IF(window == nullptr, "Window creation failed") ELSE_INFO(std::fmt("Window '%s' created with resolution '%dx%d'", name.data(), extent.width, extent.height));
|
||||
window = glfwCreateWindow(cast<i32>(extent.width), cast<i32>(extent.height), name.c_str(), (_full_screen ? monitor : nullptr), nullptr);
|
||||
ERROR_IF(window == nullptr, "Window creation failed")
|
||||
ELSE_INFO(std::fmt("Window '%s' created with resolution '%dx%d'", name.data(), extent.width, extent.height));
|
||||
if (window == nullptr) {
|
||||
auto code = GlfwContext::post_error();
|
||||
glfwTerminate();
|
||||
|
|
@ -32,27 +30,31 @@ Window::Window(const std::string_view& _title, Context* _context, vk::Extent2D _
|
|||
}
|
||||
|
||||
if (full_screen == false) {
|
||||
glfwSetWindowPos(window, (w_ - extent.width) / 2, (h_ - extent.height) / 2);
|
||||
glfwSetWindowPos(window, cast<i32>(w_ - extent.width) / 2, cast<i32>(h_ - extent.height) / 2);
|
||||
}
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
|
||||
VkSurfaceKHR surface_;
|
||||
auto result = cast<vk::Result>(glfwCreateWindowSurface(cast<VkInstance>(_context->instance), window, nullptr, &surface_));
|
||||
ERROR_IF(failed(result), "Failed to create Surface with "s + to_string(result)) THEN_CRASH(result) ELSE_INFO("Surface Created");
|
||||
surface = vk::SurfaceKHR(surface_);
|
||||
auto result = cast<vk::Result>(glfwCreateWindowSurface(cast<VkInstance>(*_context->instance), window, nullptr, &surface_));
|
||||
if (failed(result)) {
|
||||
ERROR("Failed to create Surface with "s + to_string(result));
|
||||
throw std::runtime_error("Failed to create Surface with "s + to_string(result));
|
||||
}
|
||||
INFO("Surface Created");
|
||||
surface = vk::raii::SurfaceKHR{ _context->instance, surface_ };
|
||||
}
|
||||
|
||||
Window::Window(Window&& _other) noexcept: parent_context{ std::move(_other.parent_context) }
|
||||
, window{ std::exchange(_other.window, nullptr) }
|
||||
, monitor{ _other.monitor }
|
||||
, surface{ std::exchange(_other.surface, nullptr) }
|
||||
, extent{ _other.extent }
|
||||
, name{ std::move(_other.name) }
|
||||
, full_screen{ _other.full_screen } {}
|
||||
Window::Window(Window &&_other) noexcept :
|
||||
window{ std::exchange(_other.window, nullptr) },
|
||||
monitor{ _other.monitor },
|
||||
surface{ std::exchange(_other.surface, nullptr) },
|
||||
extent{ _other.extent },
|
||||
name{ std::move(_other.name) },
|
||||
full_screen{ _other.full_screen } {}
|
||||
|
||||
Window& Window::operator=(Window&& _other) noexcept {
|
||||
if (this == &_other) return *this;
|
||||
parent_context = std::move(_other.parent_context);
|
||||
Window &Window::operator=(Window &&_other) noexcept {
|
||||
if (this == &_other)
|
||||
return *this;
|
||||
window = _other.window;
|
||||
monitor = _other.monitor;
|
||||
surface = std::exchange(_other.surface, nullptr);
|
||||
|
|
@ -63,11 +65,6 @@ Window& Window::operator=(Window&& _other) noexcept {
|
|||
}
|
||||
|
||||
Window::~Window() {
|
||||
if (parent_context && surface) {
|
||||
parent_context->instance.destroy(surface);
|
||||
INFO("Surface Destroyed");
|
||||
}
|
||||
|
||||
if (window != nullptr) {
|
||||
glfwDestroyWindow(window);
|
||||
window = nullptr;
|
||||
|
|
|
|||
|
|
@ -10,28 +10,27 @@
|
|||
#include "context.h"
|
||||
|
||||
struct Window final {
|
||||
Window(const std::string_view &_title, Context *_context, vk::Extent2D _extent, b8 _full_screen = false);
|
||||
|
||||
Window(const std::string_view& _title, Context* _context, vk::Extent2D _extent, b8 _full_screen = false);
|
||||
|
||||
Window(const Window& _other) = delete;
|
||||
Window(Window&& _other) noexcept;
|
||||
Window& operator=(const Window& _other) = delete;
|
||||
Window& operator=(Window&& _other) noexcept;
|
||||
Window(const Window &_other) = delete;
|
||||
Window(Window &&_other) noexcept;
|
||||
Window &operator=(const Window &_other) = delete;
|
||||
Window &operator=(Window &&_other) noexcept;
|
||||
|
||||
~Window();
|
||||
|
||||
bool should_close() const noexcept {
|
||||
[[nodiscard]] bool should_close() const noexcept {
|
||||
return glfwWindowShouldClose(window);
|
||||
}
|
||||
|
||||
bool poll() const noexcept {
|
||||
[[nodiscard]] bool poll() const noexcept {
|
||||
glfwPollEvents();
|
||||
return !glfwWindowShouldClose(window);
|
||||
}
|
||||
|
||||
void set_window_size(const vk::Extent2D& _extent) noexcept {
|
||||
void set_window_size(const vk::Extent2D &_extent) noexcept {
|
||||
extent = _extent;
|
||||
glfwSetWindowSize(window, extent.width, extent.height);
|
||||
glfwSetWindowSize(window, cast<i32>(extent.width), cast<i32>(extent.height));
|
||||
}
|
||||
|
||||
void set_window_size(const u32 _width, const u32 _height) noexcept {
|
||||
|
|
@ -39,11 +38,9 @@ struct Window final {
|
|||
}
|
||||
|
||||
// fields
|
||||
Context* parent_context{};
|
||||
|
||||
GLFWwindow* window{ nullptr };
|
||||
GLFWmonitor* monitor{ nullptr };
|
||||
vk::SurfaceKHR surface;
|
||||
GLFWwindow *window{ nullptr };
|
||||
GLFWmonitor *monitor{ nullptr };
|
||||
vk::raii::SurfaceKHR surface{ nullptr };
|
||||
vk::Extent2D extent;
|
||||
std::string name;
|
||||
b8 full_screen{ false };
|
||||
|
|
|
|||
Loading…
Reference in New Issue