Abstracts away vulkan Instance

This commit is contained in:
2024-06-20 06:51:25 -04:00
parent 7e6a43acb6
commit dc18a4b273
7 changed files with 348 additions and 219 deletions

View File

@@ -20,7 +20,16 @@ namespace fgl::engine
static constexpr int DEFAULT_WIDTH { 1920 };
static constexpr int DEFAULT_HEIGHT { 1080 };
vk::raii::Context ctx {};
// Window must be prepared *BEFORE* instance is ready in order to make
// glfwGetRequiredInstanceExtensions valid
Window m_window { DEFAULT_WIDTH, DEFAULT_HEIGHT, "titor Engine" };
Instance m_instance { ctx };
Device device { m_window, m_instance };
Renderer m_renderer { m_window };
//GameObject::Map game_objects {};

View File

@@ -4,6 +4,14 @@
#pragma once
#define FGL_DELETE_DEFAULT_CTOR( ClassName ) ClassName() = delete;
#define FGL_DELETE_COPY_ASSIGN( ClassName ) ClassName& operator=( const ClassName& ) = delete;
#define FGL_DELETE_COPY_CTOR( ClassName ) ClassName( const ClassName& ) = delete;
#define FGL_DELETE_MOVE_ASSIGN( ClassName ) ClassName& operator=( ClassName&& ) = delete;
#define FGL_DELETE_MOVE_CTOR( ClassName ) ClassName( ClassName&& ) = delete;
#define FGL_DELETE_COPY( ClassName ) FGL_DELETE_COPY_CTOR( ClassName ) FGL_DELETE_COPY_ASSIGN( ClassName )
#define FGL_DELETE_MOVE( ClassName ) FGL_DELETE_MOVE_CTOR( ClassName ) FGL_DELETE_MOVE_ASSIGN( ClassName )
#ifndef FGL_FORCE_NOTHING
#ifdef __GNUC__
@@ -29,6 +37,7 @@
#endif
#else
#define FGL_FLATTEN
#define FGL_FLATTEN_HOT
#define FGL_FORCE_INLINE

View File

@@ -19,7 +19,6 @@ namespace fgl::engine
m_name( window_name )
{
initWindow();
Device::init( *this );
}
Window::~Window()

View File

@@ -10,90 +10,10 @@
#include "engine/logging/logging.hpp"
PFN_vkCreateDebugUtilsMessengerEXT pfnVkCreateDebugUtilsMessengerEXT { nullptr };
PFN_vkDestroyDebugUtilsMessengerEXT pfnVkDestroyDebugUtilsMessengerEXT { nullptr };
PFN_vkSetDebugUtilsObjectNameEXT pfnVkSetDebugUtilsObjectNameEXT { nullptr };
// local callback functions
static VKAPI_ATTR vk::Bool32 VKAPI_CALL debugCallback(
[[maybe_unused]] VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
[[maybe_unused]] VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
[[maybe_unused]] void* pUserData )
{
using Bits = VkDebugUtilsMessageSeverityFlagBitsEXT;
using namespace fgl::engine;
if ( pCallbackData->flags & Bits::VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT )
{
log::info( pCallbackData->pMessage );
}
else if ( pCallbackData->flags & Bits::VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT )
{
log::warn( pCallbackData->pMessage );
}
else if ( pCallbackData->flags & Bits::VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT )
{
log::error( pCallbackData->pMessage );
std::abort();
}
else
{
//log::critical( "Unknown severity message: {}", pCallbackData->pMessage );
//std::abort();
}
return VK_FALSE;
}
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT(
VkInstance instance,
const VkDebugUtilsMessengerCreateInfoEXT* create_info,
const VkAllocationCallbacks* allocator,
VkDebugUtilsMessengerEXT* messenger )
{
return pfnVkCreateDebugUtilsMessengerEXT( instance, create_info, allocator, messenger );
}
VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT(
VkInstance instance, VkDebugUtilsMessengerEXT messenger, VkAllocationCallbacks const * pAllocator )
{
return pfnVkDestroyDebugUtilsMessengerEXT( instance, messenger, pAllocator );
}
VKAPI_ATTR VkResult VKAPI_CALL
vkSetDebugUtilsObjectNameEXT( VkDevice device, const VkDebugUtilsObjectNameInfoEXT* nameInfo )
{
return pfnVkSetDebugUtilsObjectNameEXT( device, nameInfo );
}
namespace fgl::engine
{
vk::Result CreateDebugUtilsMessengerEXT(
vk::Instance instance,
const vk::DebugUtilsMessengerCreateInfoEXT& pCreateInfo,
[[maybe_unused]] const vk::AllocationCallbacks* pAllocator,
vk::DebugUtilsMessengerEXT* pDebugMessenger )
{
return instance.createDebugUtilsMessengerEXT( &pCreateInfo, pAllocator, pDebugMessenger );
}
void DestroyDebugUtilsMessengerEXT(
vk::Instance instance,
vk::DebugUtilsMessengerEXT debugMessenger,
[[maybe_unused]] const vk::AllocationCallbacks* pAllocator )
{
instance.destroyDebugUtilsMessengerEXT( debugMessenger );
}
inline static std::unique_ptr< Device > global_device { nullptr };
Device& Device::init( Window& window )
{
global_device = std::make_unique< Device >( window );
DescriptorPool::init( *global_device );
return *global_device;
}
Device* global_device { nullptr };
Device& Device::getInstance()
{
@@ -102,15 +22,19 @@ namespace fgl::engine
}
// class member functions
Device::Device( Window& window )
Device::Device( Window& window, Instance& instance ) : m_instance( instance )
{
createInstance();
setupDebugMessenger();
assert( !global_device );
createSurface( window );
pickPhysicalDevice();
createLogicalDevice();
createVMAAllocator();
createCommandPool();
global_device = this;
DescriptorPool::init( *global_device );
}
Device::~Device()
@@ -118,61 +42,15 @@ namespace fgl::engine
vkDestroyCommandPool( m_device, m_commandPool, nullptr );
vkDestroyDevice( m_device, nullptr );
if ( enableValidationLayers )
{
DestroyDebugUtilsMessengerEXT( m_instance, m_debugMessenger, nullptr );
}
vkDestroySurfaceKHR( m_instance, m_surface_khr, nullptr );
vkDestroyInstance( m_instance, nullptr );
}
void Device::createInstance()
{
if ( enableValidationLayers && !checkValidationLayerSupport() )
{
throw std::runtime_error( "validation layers requested, but not available!" );
}
vk::ApplicationInfo appInfo {};
appInfo.pApplicationName = "Mecha Game";
appInfo.applicationVersion = VK_MAKE_VERSION( 1, 0, 0 );
appInfo.pEngineName = "titor";
appInfo.engineVersion = VK_MAKE_VERSION( 1, 0, 0 );
appInfo.apiVersion = VK_API_VERSION_1_3;
vk::InstanceCreateInfo createInfo {};
createInfo.pApplicationInfo = &appInfo;
auto extensions { getRequiredInstanceExtensions() };
assert( extensions.size() >= 1 );
createInfo.enabledExtensionCount = static_cast< uint32_t >( extensions.size() );
createInfo.ppEnabledExtensionNames = extensions.data();
hasGlfwRequiredInstanceExtensions();
vk::DebugUtilsMessengerCreateInfoEXT debugCreateInfo {};
if ( enableValidationLayers )
{
createInfo.enabledLayerCount = static_cast< uint32_t >( validationLayers.size() );
createInfo.ppEnabledLayerNames = validationLayers.data();
populateDebugMessengerCreateInfo( debugCreateInfo );
createInfo.pNext = &debugCreateInfo;
}
else
{
createInfo.enabledLayerCount = 0;
createInfo.pNext = nullptr;
}
if ( vk::createInstance( &createInfo, nullptr, &m_instance ) != vk::Result::eSuccess )
throw std::runtime_error( "Failed to create Vulkan instance" );
}
void Device::pickPhysicalDevice()
{
std::vector< vk::PhysicalDevice > devices { m_instance.enumeratePhysicalDevices() };
std::vector< vk::PhysicalDevice > devices {
static_cast< vk::Instance >( m_instance ).enumeratePhysicalDevices()
};
bool found { false };
@@ -317,57 +195,6 @@ namespace fgl::engine
return indices.isComplete() && extensionsSupported && swapChainAdequate && supportedFeatures.samplerAnisotropy;
}
void Device::populateDebugMessengerCreateInfo( vk::DebugUtilsMessengerCreateInfoEXT& createInfo )
{
createInfo.messageSeverity =
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
createInfo.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral
| vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation
| vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance;
createInfo.pfnUserCallback = debugCallback;
createInfo.pUserData = nullptr; // Optional
}
void Device::setupDebugMessenger()
{
std::cout << "Setting up debug messenger: " << std::endl;
if ( !enableValidationLayers )
{
std::cout << "-- Validation disabled" << std::endl;
return;
}
pfnVkCreateDebugUtilsMessengerEXT = reinterpret_cast<
PFN_vkCreateDebugUtilsMessengerEXT >( m_instance.getProcAddr( "vkCreateDebugUtilsMessengerEXT" ) );
pfnVkDestroyDebugUtilsMessengerEXT = reinterpret_cast<
PFN_vkDestroyDebugUtilsMessengerEXT >( m_instance.getProcAddr( "vkDestroyDebugUtilsMessengerEXT" ) );
pfnVkSetDebugUtilsObjectNameEXT =
reinterpret_cast< PFN_vkSetDebugUtilsObjectNameEXT >( m_instance
.getProcAddr( "vkSetDebugUtilsObjectNameEXT" ) );
if ( !pfnVkCreateDebugUtilsMessengerEXT || !pfnVkDestroyDebugUtilsMessengerEXT )
{
throw std::runtime_error( "failed to load debug messenger functions!" );
}
if ( !pfnVkSetDebugUtilsObjectNameEXT )
{
throw std::runtime_error( "failed to load debug object name function!" );
}
vk::DebugUtilsMessengerCreateInfoEXT createInfo {};
populateDebugMessengerCreateInfo( createInfo );
if ( CreateDebugUtilsMessengerEXT( m_instance, createInfo, nullptr, &m_debugMessenger )
!= vk::Result::eSuccess )
{
throw std::runtime_error( "failed to set up debug messenger!" );
}
std::cout << "-- Debug callback setup" << std::endl;
}
bool Device::checkValidationLayerSupport()
{
std::vector< vk::LayerProperties > availableLayers { vk::enumerateInstanceLayerProperties() };
@@ -415,34 +242,6 @@ namespace fgl::engine
return extensions;
}
void Device::hasGlfwRequiredInstanceExtensions()
{
std::vector< vk::ExtensionProperties > instance_extensions { vk::enumerateInstanceExtensionProperties() };
std::cout << "available instance instance_extensions:" << std::endl;
std::unordered_set< std::string > available;
for ( const auto& extension : instance_extensions )
{
std::cout << "\t" << extension.extensionName << std::endl;
available.insert( extension.extensionName );
}
std::cout << "required instance instance_extensions:" << std::endl;
auto requiredExtensions { getRequiredInstanceExtensions() };
for ( const char* required : requiredExtensions )
{
if ( std::find_if(
instance_extensions.begin(),
instance_extensions.end(),
[ required ]( const vk::ExtensionProperties& prop )
{ return std::strcmp( prop.extensionName, required ); } )
== instance_extensions.end() )
throw std::runtime_error( "Missing required glfw extension" );
else
std::cout << required << std::endl;
}
}
bool Device::checkDeviceExtensionSupport( vk::PhysicalDevice device )
{
const std::vector< vk::ExtensionProperties > availableExtensions {

View File

@@ -6,6 +6,7 @@
#include <string>
#include <vector>
#include "Instance.hpp"
#include "engine/Window.hpp"
#include "engine/concepts/is_suballocation.hpp"
#include "vma/vma_impl.hpp"
@@ -32,8 +33,8 @@ namespace fgl::engine
class Device
{
vk::Instance m_instance { VK_NULL_HANDLE };
vk::DebugUtilsMessengerEXT m_debugMessenger { VK_NULL_HANDLE };
Instance& m_instance;
vk::PhysicalDevice m_physical_device { VK_NULL_HANDLE };
vk::CommandPool m_commandPool { VK_NULL_HANDLE };
@@ -59,7 +60,8 @@ namespace fgl::engine
vk::PhysicalDeviceProperties m_properties {};
static Device& init( Window& window );
Device( Window& window, Instance& );
static Device& getInstance();
template < typename Dst, typename Src >
@@ -83,7 +85,6 @@ namespace fgl::engine
private:
void createInstance();
void setupDebugMessenger();
void createSurface( Window& window );
void pickPhysicalDevice();
@@ -96,8 +97,6 @@ namespace fgl::engine
std::vector< const char* > getRequiredInstanceExtensions();
bool checkValidationLayerSupport();
QueueFamilyIndices findQueueFamilies( vk::PhysicalDevice device );
void populateDebugMessengerCreateInfo( vk::DebugUtilsMessengerCreateInfoEXT& createInfo );
void hasGlfwRequiredInstanceExtensions();
bool checkDeviceExtensionSupport( vk::PhysicalDevice device );
SwapChainSupportDetails querySwapChainSupport( vk::PhysicalDevice device );

View File

@@ -0,0 +1,263 @@
//
// Created by kj16609 on 6/20/24.
//
#include "Instance.hpp"
#include <GLFW/glfw3.h>
#include <unordered_set>
#include "engine/logging/logging.hpp"
PFN_vkCreateDebugUtilsMessengerEXT pfnVkCreateDebugUtilsMessengerEXT { nullptr };
PFN_vkDestroyDebugUtilsMessengerEXT pfnVkDestroyDebugUtilsMessengerEXT { nullptr };
PFN_vkSetDebugUtilsObjectNameEXT pfnVkSetDebugUtilsObjectNameEXT { nullptr };
// Callback function for vulkan messaging.
static VKAPI_ATTR vk::Bool32 VKAPI_CALL debugCallback(
[[maybe_unused]] VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
[[maybe_unused]] VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
[[maybe_unused]] void* pUserData )
{
using Bits = VkDebugUtilsMessageSeverityFlagBitsEXT;
using namespace fgl::engine;
if ( pCallbackData->flags & Bits::VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT )
{
log::info( pCallbackData->pMessage );
}
else if ( pCallbackData->flags & Bits::VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT )
{
log::warn( pCallbackData->pMessage );
}
else if ( pCallbackData->flags & Bits::VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT )
{
log::error( pCallbackData->pMessage );
std::abort();
}
else
{
//log::critical( "Unknown severity message: {}", pCallbackData->pMessage );
//std::abort();
}
return VK_FALSE;
}
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT(
VkInstance instance,
const VkDebugUtilsMessengerCreateInfoEXT* create_info,
const VkAllocationCallbacks* allocator,
VkDebugUtilsMessengerEXT* messenger )
{
assert( pfnVkCreateDebugUtilsMessengerEXT );
return pfnVkCreateDebugUtilsMessengerEXT( instance, create_info, allocator, messenger );
}
VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT(
VkInstance instance, VkDebugUtilsMessengerEXT messenger, VkAllocationCallbacks const * pAllocator )
{
assert( pfnVkDestroyDebugUtilsMessengerEXT );
return pfnVkDestroyDebugUtilsMessengerEXT( instance, messenger, pAllocator );
}
VKAPI_ATTR VkResult VKAPI_CALL
vkSetDebugUtilsObjectNameEXT( VkDevice device, const VkDebugUtilsObjectNameInfoEXT* nameInfo )
{
assert( pfnVkSetDebugUtilsObjectNameEXT );
return pfnVkSetDebugUtilsObjectNameEXT( device, nameInfo );
}
namespace fgl::engine
{
vk::Result CreateDebugUtilsMessengerEXT(
vk::Instance instance,
const vk::DebugUtilsMessengerCreateInfoEXT& pCreateInfo,
[[maybe_unused]] const vk::AllocationCallbacks* pAllocator,
vk::DebugUtilsMessengerEXT* pDebugMessenger )
{
return instance.createDebugUtilsMessengerEXT( &pCreateInfo, pAllocator, pDebugMessenger );
}
void DestroyDebugUtilsMessengerEXT(
vk::Instance instance,
vk::DebugUtilsMessengerEXT debugMessenger,
[[maybe_unused]] const vk::AllocationCallbacks* pAllocator )
{
instance.destroyDebugUtilsMessengerEXT( debugMessenger );
}
vk::ApplicationInfo Instance::appInfo()
{
vk::ApplicationInfo info {};
info.pApplicationName = "Mecha Game";
info.applicationVersion = VK_MAKE_VERSION( 1, 0, 0 );
info.pEngineName = "titor";
info.engineVersion = VK_MAKE_VERSION( 1, 0, 0 );
info.apiVersion = VK_API_VERSION_1_3;
return info;
}
vk::InstanceCreateInfo Instance::
createInfo( vk::ApplicationInfo* app_info, vk::DebugUtilsMessengerCreateInfoEXT* msger_info )
{
vk::InstanceCreateInfo info {};
info.pApplicationInfo = app_info;
assert( m_required_extensions.size() >= 1 );
info.enabledExtensionCount = static_cast< uint32_t >( m_required_extensions.size() );
info.ppEnabledExtensionNames = m_required_extensions.data();
verifyGlfwExtensions();
const static std::vector< const char* > validationLayers { "VK_LAYER_KHRONOS_validation" };
if ( ENABLE_VALIDATION_LAYERS )
{
info.enabledLayerCount = static_cast< uint32_t >( validationLayers.size() );
info.ppEnabledLayerNames = validationLayers.data();
info.pNext = msger_info;
}
else
{
info.enabledLayerCount = 0;
info.pNext = nullptr;
}
return info;
}
std::vector< const char* > Instance::getRequiredInstanceExtensions()
{
uint32_t glfwExtensionCount = 0;
const char** glfwExtensions { glfwGetRequiredInstanceExtensions( &glfwExtensionCount ) };
if ( glfwExtensions == nullptr ) throw std::runtime_error( "Failed to get required extensions from glfw" );
std::vector< const char* > extensions( glfwExtensions, glfwExtensions + glfwExtensionCount );
// "VK_KHR_surface" is guaranteed to be in this list
assert( extensions.size() >= 1 );
if ( ENABLE_VALIDATION_LAYERS )
{
extensions.push_back( VK_EXT_DEBUG_UTILS_EXTENSION_NAME );
}
return extensions;
}
vk::DebugUtilsMessengerCreateInfoEXT Instance::createDebugMessengerInfo()
{
vk::DebugUtilsMessengerCreateInfoEXT create_info {};
create_info.messageSeverity =
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
create_info.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral
| vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation
| vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance;
create_info.pfnUserCallback = debugCallback;
create_info.pUserData = nullptr; // Optional
return create_info;
}
void Instance::verifyGlfwExtensions()
{
std::vector< vk::ExtensionProperties > instance_extensions { vk::enumerateInstanceExtensionProperties() };
std::cout << "available instance instance_extensions:" << std::endl;
std::unordered_set< std::string > available {};
//Get list of all available instance extensions
for ( const auto& extension : instance_extensions )
{
std::cout << "\t" << extension.extensionName << std::endl;
available.insert( extension.extensionName );
}
std::cout << "required instance instance_extensions:" << std::endl;
//Get the list of the required extensions
auto requiredExtensions { getRequiredInstanceExtensions() };
for ( const char* required : requiredExtensions )
{
if ( std::find_if(
instance_extensions.begin(),
instance_extensions.end(),
[ required ]( const vk::ExtensionProperties& prop )
{ return std::strcmp( prop.extensionName, required ); } )
== instance_extensions.end() )
{
log::critical( "Failed to find required extention: {}", std::string_view( required ) );
throw std::runtime_error( "Failed to find required extention: " );
}
else
std::cout << required << std::endl;
}
}
void Instance::setupDebugMessenger()
{
if ( !ENABLE_VALIDATION_LAYERS )
{
log::info( "Validation disabled. Skipping debug messenger" );
return;
}
log::info( "Setting up debug messenger" );
pfnVkCreateDebugUtilsMessengerEXT = reinterpret_cast<
PFN_vkCreateDebugUtilsMessengerEXT >( m_instance.getProcAddr( "vkCreateDebugUtilsMessengerEXT" ) );
pfnVkDestroyDebugUtilsMessengerEXT = reinterpret_cast<
PFN_vkDestroyDebugUtilsMessengerEXT >( m_instance.getProcAddr( "vkDestroyDebugUtilsMessengerEXT" ) );
pfnVkSetDebugUtilsObjectNameEXT =
reinterpret_cast< PFN_vkSetDebugUtilsObjectNameEXT >( m_instance
.getProcAddr( "vkSetDebugUtilsObjectNameEXT" ) );
if ( !pfnVkCreateDebugUtilsMessengerEXT || !pfnVkDestroyDebugUtilsMessengerEXT )
{
log::critical(
"Failed to load create/destroy messenger functions pfnVkCreateDebugUtilsMessengerEXT/pfnVkDestroyDebugUtilsMessengerEXT" );
throw std::runtime_error( "failed to load debug messenger functions!" );
}
if ( !pfnVkSetDebugUtilsObjectNameEXT )
{
log::critical( "Failed to load debug object naming function: pfnVkSetDebugUtilsObjectNameEXT" );
throw std::runtime_error( "failed to load debug object name function!" );
}
if ( CreateDebugUtilsMessengerEXT( m_instance, m_debug_info, nullptr, &m_debug_messenger )
!= vk::Result::eSuccess )
{
throw std::runtime_error( "failed to set up debug messenger!" );
}
log::info( "Debug callback setup" );
}
Instance::Instance( vk::raii::Context& ctx ) :
m_app_info( appInfo() ),
m_debug_info( createDebugMessengerInfo() ),
m_required_extensions( getRequiredInstanceExtensions() ),
m_instance_info( createInfo( &m_app_info, &m_debug_info ) ),
m_instance( ctx, m_instance_info )
{
//Post setup.
setupDebugMessenger();
}
Instance::~Instance()
{
if ( ENABLE_VALIDATION_LAYERS )
{
DestroyDebugUtilsMessengerEXT( m_instance, m_debug_messenger, nullptr );
}
}
} // namespace fgl::engine

View File

@@ -0,0 +1,51 @@
//
// Created by kj16609 on 6/20/24.
//
#pragma once
#include <vulkan/vulkan_raii.hpp>
#include "engine/FGL_DEFINES.hpp"
namespace fgl::engine
{
class Instance
{
static constexpr bool ENABLE_VALIDATION_LAYERS { true };
vk::ApplicationInfo m_app_info;
vk::DebugUtilsMessengerCreateInfoEXT m_debug_info;
std::vector< const char* > m_required_extensions;
vk::InstanceCreateInfo m_instance_info;
vk::raii::Instance m_instance;
vk::DebugUtilsMessengerEXT m_debug_messenger { VK_NULL_HANDLE };
vk::ApplicationInfo appInfo();
vk::DebugUtilsMessengerCreateInfoEXT createDebugMessengerInfo();
vk::InstanceCreateInfo
createInfo( vk::ApplicationInfo* info, vk::DebugUtilsMessengerCreateInfoEXT* msger_info );
std::vector< const char* > getRequiredInstanceExtensions();
void verifyGlfwExtensions();
void setupDebugMessenger();
public:
FGL_DELETE_DEFAULT_CTOR( Instance )
FGL_DELETE_COPY( Instance )
FGL_DELETE_MOVE( Instance )
Instance( vk::raii::Context& ctx );
~Instance();
inline operator vk::Instance() { return m_instance; }
inline operator VkInstance() { return *m_instance; }
};
} // namespace fgl::engine