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 "constants.h"
|
||||||
#include "glfw_context.h"
|
#include "glfw_context.h"
|
||||||
#include "window.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();
|
while (window.poll()) {
|
||||||
Context* context = new Context("Aster", VERSION);
|
}
|
||||||
Window* window = new Window("Aster1", context, { 640, 480 });
|
|
||||||
|
|
||||||
delete window;
|
|
||||||
delete context;
|
|
||||||
delete glfw;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
|
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
|
||||||
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
||||||
#define VULKAN_HPP_NO_EXCEPTIONS
|
|
||||||
|
|
||||||
#if defined(NDEBUG)
|
#if defined(NDEBUG)
|
||||||
#define USE_OPTICK (0)
|
#define USE_OPTICK (0)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include "context.h"
|
#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 Severity = vk::DebugUtilsMessageSeverityFlagsEXT;
|
||||||
using SeverityBits = vk::DebugUtilsMessageSeverityFlagBitsEXT;
|
using SeverityBits = vk::DebugUtilsMessageSeverityFlagBitsEXT;
|
||||||
using MessageType = vk::DebugUtilsMessageTypeFlagsEXT;
|
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) {
|
void Context::init(const std::string_view &_app_name, const Version &_app_version) {
|
||||||
vk::Result result;
|
|
||||||
|
|
||||||
INFO_IF(enable_validation_layers, "Validation Layers enabled");
|
INFO_IF(enable_validation_layers, "Validation Layers enabled");
|
||||||
|
|
||||||
// Creating Instance
|
// 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");
|
const auto vkGetInstanceProcAddr = dl.getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
|
||||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(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,
|
.pNext = enable_validation_layers ? &debug_messenger_create_info : nullptr,
|
||||||
.pApplicationInfo = &app_info,
|
.pApplicationInfo = &app_info,
|
||||||
.enabledLayerCount = enable_validation_layers ? cast<u32>(validation_layers.size()) : 0,
|
.enabledLayerCount = enable_validation_layers ? cast<u32>(validation_layers.size()) : 0,
|
||||||
.ppEnabledLayerNames = enable_validation_layers ? validation_layers.data() : nullptr,
|
.ppEnabledLayerNames = enable_validation_layers ? validation_layers.data() : nullptr,
|
||||||
.enabledExtensionCount = cast<u32>(vulkan_extensions.size()),
|
.enabledExtensionCount = cast<u32>(vulkan_extensions.size()),
|
||||||
.ppEnabledExtensionNames = vulkan_extensions.data(),
|
.ppEnabledExtensionNames = vulkan_extensions.data(),
|
||||||
});
|
} };
|
||||||
ERROR_IF(failed(result), "Failed to create Vulkan instance with "s + to_string(result))
|
} catch (const std::exception &err) {
|
||||||
THEN_CRASH(result)
|
ERROR("Failed to create Vulkan instance with "s + err.what());
|
||||||
ELSE_INFO("Instance Created.");
|
throw err;
|
||||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
|
}
|
||||||
|
INFO("Instance Created.");
|
||||||
|
|
||||||
// Debug Messenger
|
// Debug Messenger
|
||||||
if (enable_validation_layers) {
|
if (enable_validation_layers) {
|
||||||
tie(result, debug_messenger) = instance.createDebugUtilsMessengerEXT(debug_messenger_create_info);
|
try {
|
||||||
ERROR_IF(failed(result), "Debug Messenger creation failed with "s + to_string(result))
|
debug_messenger = vk::raii::DebugUtilsMessengerEXT{ instance, debug_messenger_create_info };
|
||||||
ELSE_INFO("Debug Messenger Created.");
|
} catch (const std::exception &err) {
|
||||||
|
ERROR("Debug Messenger creation failed with "s + err.what());
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
INFO("Debug Messenger Created.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Context::~Context() {
|
Context::~Context() = default;
|
||||||
if (instance) {
|
|
||||||
if (enable_validation_layers && debug_messenger) {
|
|
||||||
instance.destroyDebugUtilsMessengerEXT(debug_messenger);
|
|
||||||
}
|
|
||||||
instance.destroy();
|
|
||||||
INFO("Context destroyed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,9 @@ public:
|
||||||
VK_KHR_MULTIVIEW_EXTENSION_NAME,
|
VK_KHR_MULTIVIEW_EXTENSION_NAME,
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::Instance instance;
|
vk::raii::Context raii_context;
|
||||||
vk::DebugUtilsMessengerEXT debug_messenger;
|
vk::raii::Instance instance{ nullptr };
|
||||||
|
vk::raii::DebugUtilsMessengerEXT debug_messenger{ nullptr };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(const std::string_view &_app_name, const Version &_app_version);
|
void init(const std::string_view &_app_name, const Version &_app_version);
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define VULKAN_HPP_ASSERT(expr) DEBUG_IF(!(expr), "Vulkan assert failed")
|
#define VULKAN_HPP_ASSERT(expr) DEBUG_IF(!(expr), "Vulkan assert failed")
|
||||||
#include <vulkan/vulkan.hpp>
|
|
||||||
#include <vk_mem_alloc.h>
|
#include <vk_mem_alloc.h>
|
||||||
|
#include <vulkan/vulkan_raii.hpp>
|
||||||
|
|
||||||
#define CODE_LOC " @ " __FILE__ ":" VULKAN_HPP_STRINGIFY(__LINE__)
|
#define CODE_LOC " @ " __FILE__ ":" VULKAN_HPP_STRINGIFY(__LINE__)
|
||||||
[[nodiscard]] inline bool failed(const vk::Result _result) {
|
[[nodiscard]] inline bool failed(const vk::Result _result) {
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,13 @@
|
||||||
// =============================================
|
// =============================================
|
||||||
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "logger.h"
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "glfw_context.h"
|
#include "glfw_context.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
Window::Window(const std::string_view& _title, Context* _context, vk::Extent2D _extent, b8 _full_screen)
|
Window::Window(const std::string_view &_title, Context *_context, const vk::Extent2D _extent, const bool _full_screen) :
|
||||||
: parent_context{ std::move(_context) }
|
extent{ _extent }, name{ _title } {
|
||||||
, extent{ _extent }
|
full_screen = _full_screen;
|
||||||
, name{ _title }
|
|
||||||
, full_screen{ _full_screen } {
|
|
||||||
|
|
||||||
monitor = glfwGetPrimaryMonitor();
|
monitor = glfwGetPrimaryMonitor();
|
||||||
ERROR_IF(monitor == nullptr, "No monitor found");
|
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_CLIENT_API, GLFW_NO_API);
|
||||||
glfwWindowHint(GLFW_CENTER_CURSOR, GLFW_TRUE);
|
glfwWindowHint(GLFW_CENTER_CURSOR, GLFW_TRUE);
|
||||||
|
|
||||||
window = glfwCreateWindow(extent.width, extent.height, name.data(), full_screen ? monitor : nullptr, nullptr);
|
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));
|
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) {
|
if (window == nullptr) {
|
||||||
auto code = GlfwContext::post_error();
|
auto code = GlfwContext::post_error();
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
@ -32,27 +30,31 @@ Window::Window(const std::string_view& _title, Context* _context, vk::Extent2D _
|
||||||
}
|
}
|
||||||
|
|
||||||
if (full_screen == false) {
|
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);
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
|
|
||||||
VkSurfaceKHR surface_;
|
VkSurfaceKHR surface_;
|
||||||
auto result = cast<vk::Result>(glfwCreateWindowSurface(cast<VkInstance>(_context->instance), window, nullptr, &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");
|
if (failed(result)) {
|
||||||
surface = vk::SurfaceKHR(surface_);
|
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::Window(Window &&_other) noexcept :
|
||||||
, window{ std::exchange(_other.window, nullptr) }
|
window{ std::exchange(_other.window, nullptr) },
|
||||||
, monitor{ _other.monitor }
|
monitor{ _other.monitor },
|
||||||
, surface{ std::exchange(_other.surface, nullptr) }
|
surface{ std::exchange(_other.surface, nullptr) },
|
||||||
, extent{ _other.extent }
|
extent{ _other.extent },
|
||||||
, name{ std::move(_other.name) }
|
name{ std::move(_other.name) },
|
||||||
, full_screen{ _other.full_screen } {}
|
full_screen{ _other.full_screen } {}
|
||||||
|
|
||||||
Window& Window::operator=(Window&& _other) noexcept {
|
Window &Window::operator=(Window &&_other) noexcept {
|
||||||
if (this == &_other) return *this;
|
if (this == &_other)
|
||||||
parent_context = std::move(_other.parent_context);
|
return *this;
|
||||||
window = _other.window;
|
window = _other.window;
|
||||||
monitor = _other.monitor;
|
monitor = _other.monitor;
|
||||||
surface = std::exchange(_other.surface, nullptr);
|
surface = std::exchange(_other.surface, nullptr);
|
||||||
|
|
@ -63,11 +65,6 @@ Window& Window::operator=(Window&& _other) noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::~Window() {
|
Window::~Window() {
|
||||||
if (parent_context && surface) {
|
|
||||||
parent_context->instance.destroy(surface);
|
|
||||||
INFO("Surface Destroyed");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window != nullptr) {
|
if (window != nullptr) {
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
window = nullptr;
|
window = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -10,28 +10,27 @@
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
|
||||||
struct Window final {
|
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(const Window& _other) = delete;
|
Window &operator=(const Window &_other) = delete;
|
||||||
Window(Window&& _other) noexcept;
|
Window &operator=(Window &&_other) noexcept;
|
||||||
Window& operator=(const Window& _other) = delete;
|
|
||||||
Window& operator=(Window&& _other) noexcept;
|
|
||||||
|
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
bool should_close() const noexcept {
|
[[nodiscard]] bool should_close() const noexcept {
|
||||||
return glfwWindowShouldClose(window);
|
return glfwWindowShouldClose(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool poll() const noexcept {
|
[[nodiscard]] bool poll() const noexcept {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
return !glfwWindowShouldClose(window);
|
return !glfwWindowShouldClose(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_window_size(const vk::Extent2D& _extent) noexcept {
|
void set_window_size(const vk::Extent2D &_extent) noexcept {
|
||||||
extent = _extent;
|
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 {
|
void set_window_size(const u32 _width, const u32 _height) noexcept {
|
||||||
|
|
@ -39,11 +38,9 @@ struct Window final {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fields
|
// fields
|
||||||
Context* parent_context{};
|
GLFWwindow *window{ nullptr };
|
||||||
|
GLFWmonitor *monitor{ nullptr };
|
||||||
GLFWwindow* window{ nullptr };
|
vk::raii::SurfaceKHR surface{ nullptr };
|
||||||
GLFWmonitor* monitor{ nullptr };
|
|
||||||
vk::SurfaceKHR surface;
|
|
||||||
vk::Extent2D extent;
|
vk::Extent2D extent;
|
||||||
std::string name;
|
std::string name;
|
||||||
b8 full_screen{ false };
|
b8 full_screen{ false };
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue