device suitability is in a better place now

This commit is contained in:
Ben Kyd
2023-11-04 18:58:58 +00:00
parent cf1c6be4cb
commit c4f65d6599
9 changed files with 1298 additions and 157 deletions

View File

@@ -66,6 +66,7 @@ else()
target_link_libraries(inferno PRIVATE
${GLFW3_LIBRARIES}
Vulkan::Vulkan
libvulkan.so
OpenMP::OpenMP_CXX
)
endif()

View File

@@ -3,13 +3,25 @@
// easy include for graphics shit
// Include GLFW and ImGUI
#ifdef _WIN32
#define VK_USE_PLATFORM_WIN32_KHR
#define GLFW_EXPOSE_NATIVE_WIN32
#include <windows.h>
#else
#define VK_USE_PLATFORM_XLIB_KHR
#define GLFW_EXPOSE_NATIVE_X11
#include <X11/Xlib.h>
#endif
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#include <vulkan/vulkan_xlib.h>
#include <GLFW/glfw3native.h>
#include "imgui/imgui.h"
#include "imgui/imgui_internal.h"
#include "imgui/imgui_impl_vulkan.h"
#include "imgui/imgui_impl_glfw.h"
#include "imgui/imgui_impl_vulkan.h"
#include "imgui/imgui_internal.h"
// glm
#define GLM_FORCE_SWIZZLE
@@ -19,7 +31,7 @@
#include <vector>
namespace inferno {
namespace graphics::rays {
class Ray;
class Ray;
}
using RayField = std::vector<graphics::rays::Ray*>;
}

View File

@@ -0,0 +1,150 @@
// Scheme for the various vkGet* and vkEnumerate* commands
//
// Following the DRY principle, this implements getting a vector of enumerants
// from the similar enumeration commands that return VK_INCOMPELTE.
#pragma once
#include <functional>
#include <type_traits>
#include <vector>
#include <vulkan/vulkan.h>
#include "errorhandling.hpp"
// the enumeration scheme
// takes function VkResult cmd( uint32_t count, Element* pArray ) and Vulkan command name (for debugging purposes)
// returns vector<Element> which contains the enumerants, or throws
template< typename Element, typename Cmd >
std::vector<Element> enumerateScheme( Cmd cmd, const char* cmdName ){
std::vector<Element> enumerants;
VkResult errorCode;
uint32_t enumerantsCount;
// repeat until complete array is returned, or error
do{
errorCode = cmd( &enumerantsCount, nullptr ); RESULT_HANDLER( errorCode, cmdName ); // get current array size
enumerants.resize( enumerantsCount );
errorCode = cmd( &enumerantsCount, enumerants.data() ); // get current array up to enumerantsCount
} while( errorCode == VK_INCOMPLETE );
RESULT_HANDLER( errorCode, cmdName );
enumerants.resize( enumerantsCount ); // shrink in case of enumerantsCount1 > enumerantsCount2
enumerants.shrink_to_fit(); // unlikely the vector will grow from this point on anyway
return enumerants;
}
// Adapters for specific Vulkan commands
///////////////////////////////////////////////
template< typename Element, typename... Ts, typename = std::enable_if_t<!std::is_same<Element, VkInstance>::value> >
std::vector<Element> enumerate( Ts... );
// Tag will be VkInstance if to disambiguate commands that also work on device
template< typename Tag, typename Element, typename... Ts, typename = std::enable_if_t<std::is_same<Tag, VkInstance>::value> >
std::vector<Element> enumerate( Ts... );
// for vkEnumerateInstanceLayerProperties -- auto v = enumerate<VkInstance, VkLayerProperties>();
template<>
std::vector<VkLayerProperties> enumerate<VkInstance, VkLayerProperties>(){
return enumerateScheme<VkLayerProperties>( vkEnumerateInstanceLayerProperties, "vkEnumerateInstanceLayerProperties" );
}
// for vkEnumerateDeviceLayerProperties -- auto v = enumerate<VkLayerProperties>( pd );
template<>
std::vector<VkLayerProperties> enumerate<VkLayerProperties, VkPhysicalDevice>( VkPhysicalDevice physicalDevice ){
using namespace std::placeholders;
const auto cmd = vkEnumerateDeviceLayerProperties;
const auto adapterCmd = std::bind( cmd, physicalDevice, _1, _2 );
return enumerateScheme<VkLayerProperties>( adapterCmd, "vkEnumerateDeviceLayerProperties" );
}
// for vkEnumerateInstanceExtensionProperties -- auto v = enumerate<VkInstance, VkExtensionProperties>( "ln" );
template<>
std::vector<VkExtensionProperties> enumerate<VkInstance, VkExtensionProperties, const char*>( const char* pLayerName ){
using namespace std::placeholders;
const auto cmd = vkEnumerateInstanceExtensionProperties;
const auto adapterCmd = std::bind( cmd, pLayerName, _1, _2 );
return enumerateScheme<VkExtensionProperties>( adapterCmd, "vkEnumerateInstanceExtensionProperties" );
}
// for vkEnumerateInstanceExtensionProperties with nullptr layer -- auto v = enumerate<VkInstance, VkExtensionProperties>();
template<>
std::vector<VkExtensionProperties> enumerate<VkInstance, VkExtensionProperties>(){
using namespace std::placeholders;
const auto cmd = vkEnumerateInstanceExtensionProperties;
const auto adapterCmd = std::bind( cmd, nullptr, _1, _2 );
return enumerateScheme<VkExtensionProperties>( adapterCmd, "vkEnumerateInstanceExtensionProperties" );
}
// for vkEnumerateDeviceExtensionProperties -- auto v = enumerate<VkExtensionProperties>( pd, "ln" );
template<>
std::vector<VkExtensionProperties> enumerate<VkExtensionProperties, VkPhysicalDevice, const char*>( VkPhysicalDevice physicalDevice, const char* pLayerName ){
using namespace std::placeholders;
const auto cmd = vkEnumerateDeviceExtensionProperties;
const auto adapterCmd = std::bind( cmd, physicalDevice, pLayerName, _1, _2 );
return enumerateScheme<VkExtensionProperties>( adapterCmd, "vkEnumerateDeviceExtensionProperties" );
}
// for vkEnumerateInstanceExtensionProperties with nullptr layer -- auto v = enumerate<VkExtensionProperties>( pd );
template<>
std::vector<VkExtensionProperties> enumerate<VkExtensionProperties, VkPhysicalDevice>( VkPhysicalDevice physicalDevice ){
using namespace std::placeholders;
const auto cmd = vkEnumerateDeviceExtensionProperties;
const auto adapterCmd = std::bind( cmd, physicalDevice, nullptr, _1, _2 );
return enumerateScheme<VkExtensionProperties>( adapterCmd, "vkEnumerateDeviceExtensionProperties" );
}
// for vkEnumeratePhysicalDevices -- auto v = enumerate<VkPhysicalDevice>( i );
template<>
std::vector<VkPhysicalDevice> enumerate<VkPhysicalDevice, VkInstance>( VkInstance instance ){
using namespace std::placeholders;
const auto cmd = vkEnumeratePhysicalDevices;
const auto adapterCmd = std::bind( cmd, instance, _1, _2 );
return enumerateScheme<VkPhysicalDevice>( adapterCmd, "vkEnumeratePhysicalDevices" );
}
// for vkGetPhysicalDeviceSurfaceFormatsKHR -- auto v = enumerate<VkSurfaceFormatKHR>( pd, s );
template<>
std::vector<VkSurfaceFormatKHR> enumerate<VkSurfaceFormatKHR, VkPhysicalDevice, VkSurfaceKHR>( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface ){
using namespace std::placeholders;
const auto cmd = vkGetPhysicalDeviceSurfaceFormatsKHR;
const auto adapterCmd = std::bind( cmd, physicalDevice, surface, _1, _2 );
return enumerateScheme<VkSurfaceFormatKHR>( adapterCmd, "vkGetPhysicalDeviceSurfaceFormatsKHR" );
}
// for vkGetPhysicalDeviceSurfacePresentModesKHR -- auto v = enumerate<VkSurfaceFormatKHR>( pd, s );
template<>
std::vector<VkPresentModeKHR> enumerate<VkPresentModeKHR, VkPhysicalDevice, VkSurfaceKHR>( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface ){
using namespace std::placeholders;
const auto cmd = vkGetPhysicalDeviceSurfacePresentModesKHR;
const auto adapterCmd = std::bind( cmd, physicalDevice, surface, _1, _2 );
return enumerateScheme<VkPresentModeKHR>( adapterCmd, "vkGetPhysicalDeviceSurfacePresentModesKHR" );
}
// for vkGetSwapchainImagesKHR -- auto v = enumerate<VkSurfaceFormatKHR>( d, s );
template<>
std::vector<VkImage> enumerate<VkImage, VkDevice, VkSwapchainKHR>( VkDevice device, VkSwapchainKHR swapchain ){
using namespace std::placeholders;
const auto cmd = vkGetSwapchainImagesKHR;
const auto adapterCmd = std::bind( cmd, device, swapchain, _1, _2 );
return enumerateScheme<VkImage>( adapterCmd, "vkGetSwapchainImagesKHR" );
}
// ... others to be added as needed

View File

@@ -0,0 +1,203 @@
// Reusable error handling primitives for Vulkan
#pragma once
#include <iostream>
#include <string>
#include <sstream>
#include <vulkan/vulkan.h>
#include "vulkanintrospection.hpp"
struct VulkanResultException{
const char* file;
unsigned line;
const char* func;
const char* source;
VkResult result;
VulkanResultException( const char* file, unsigned line, const char* func, const char* source, VkResult result )
: file( file ), line( line ), func( func ), source( source ), result( result ){}
};
#define RESULT_HANDLER( errorCode, source ) if( errorCode ) throw VulkanResultException( __FILE__, __LINE__, __func__, source, errorCode )
#define RESULT_HANDLER_EX( cond, errorCode, source ) if( cond ) throw VulkanResultException( __FILE__, __LINE__, __func__, source, errorCode )
#define RUNTIME_ASSERT( cond, source ) if( !(cond) ) throw source " failed";
// just use cout for logging now
std::ostream& logger = std::cout;
enum class Highlight{ off, on };
void genericDebugCallback( std::string flags, Highlight highlight, std::string msgCode, std::string object, const char* message );
VKAPI_ATTR VkBool32 VKAPI_CALL genericDebugReportCallback(
VkDebugReportFlagsEXT msgFlags,
VkDebugReportObjectTypeEXT objType,
uint64_t srcObject,
size_t /*location*/,
int32_t msgCode,
const char* pLayerPrefix,
const char* pMsg,
void* /*pUserData*/
);
VKAPI_ATTR VkBool32 VKAPI_CALL genericDebugUtilsCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* /*pUserData*/
);
enum class DebugObjectType{ debugReport, debugUtils } tag;
struct DebugObjectVariant{
DebugObjectType tag;
union{
VkDebugReportCallbackEXT debugReportCallback;
VkDebugUtilsMessengerEXT debugUtilsMessenger;
};
};
DebugObjectVariant initDebug( const VkInstance instance, const DebugObjectType debugExtension, const VkDebugUtilsMessageSeverityFlagsEXT debugSeverity, const VkDebugUtilsMessageTypeFlagsEXT debugType );
void killDebug( VkInstance instance, DebugObjectVariant debug );
VkDebugReportFlagsEXT translateFlags( const VkDebugUtilsMessageSeverityFlagsEXT debugSeverity, const VkDebugUtilsMessageTypeFlagsEXT debugType );
// Implementation
//////////////////////////////////
void genericDebugCallback( std::string flags, Highlight highlight, std::string msgCode, std::string object, const char* message ){
using std::endl;
using std::string;
const string report = flags + ": " + object + ": " + msgCode + ", \"" + message + '"';
if( highlight != Highlight::off ){
const string border( 80, '!' );
logger << border << endl;
logger << report << endl;
logger << border << endl << endl;
}
else{
logger << report << endl;
}
}
VKAPI_ATTR VkBool32 VKAPI_CALL genericDebugReportCallback(
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object,
size_t /*location*/,
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage,
void* /*pUserData*/
){
using std::to_string;
using std::string;
Highlight highlight;
if( (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) || (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) || (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) ){
highlight = Highlight::on;
}
else highlight = Highlight::off;
genericDebugCallback( dbrflags_to_string( flags ), highlight, string(pLayerPrefix) + ", " + to_string( messageCode ), to_string( objectType ) + "(" + to_string_hex( object ) + ")", pMessage );
return VK_FALSE; // no abort on misbehaving command
}
VKAPI_ATTR VkBool32 VKAPI_CALL genericDebugUtilsCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* /*pUserData*/
){
using std::to_string;
using std::string;
Highlight highlight;
if( (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) || (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)){
highlight = Highlight::on;
}
else highlight = Highlight::off;
string objects;
bool first = true;
for( uint32_t i = 0; i < pCallbackData->objectCount; ++i ){
const auto& obj = pCallbackData->pObjects[i];
if( first ) first = false;
else objects += ", ";
objects += to_string( obj.objectType ) + "(" + to_string_hex( obj.objectHandle ) + ")";
}
objects = "[" + objects + "]";
genericDebugCallback( dbutype_to_string( messageTypes ) + "+" + to_string( messageSeverity ), highlight, string(pCallbackData->pMessageIdName) + "(" + to_string( pCallbackData->messageIdNumber ) + ")", objects, pCallbackData->pMessage );
return VK_FALSE; // no abort on misbehaving command
}
VkDebugReportFlagsEXT translateFlags( const VkDebugUtilsMessageSeverityFlagsEXT debugSeverity, const VkDebugUtilsMessageTypeFlagsEXT debugType ){
VkDebugReportFlagsEXT flags = 0;
if( (debugType & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) || (debugType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) ){
if( debugSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT ) flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
if( debugSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT ) flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
if( (debugSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) && (debugType & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) ) flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
if( debugSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT ) flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
if( debugSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT ) flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
}
return flags;
}
DebugObjectVariant initDebug( const VkInstance instance, const DebugObjectType debugExtension, const VkDebugUtilsMessageSeverityFlagsEXT debugSeverity, const VkDebugUtilsMessageTypeFlagsEXT debugType ){
DebugObjectVariant debug;
debug.tag = debugExtension;
if( debugExtension == DebugObjectType::debugUtils ){
const VkDebugUtilsMessengerCreateInfoEXT dmci = {
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
nullptr, // pNext
0, // flags
debugSeverity,
debugType,
::genericDebugUtilsCallback,
nullptr // pUserData
};
const VkResult errorCode = vkCreateDebugUtilsMessengerEXT( instance, &dmci, nullptr, &debug.debugUtilsMessenger ); RESULT_HANDLER( errorCode, "vkCreateDebugUtilsMessengerEXT" );
}
else if( debugExtension == DebugObjectType::debugReport ){
const VkDebugReportCallbackCreateInfoEXT debugCreateInfo{
VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
nullptr, // pNext
translateFlags( debugSeverity, debugType ),
::genericDebugReportCallback,
nullptr // pUserData
};
const VkResult errorCode = vkCreateDebugReportCallbackEXT( instance, &debugCreateInfo, nullptr, &debug.debugReportCallback ); RESULT_HANDLER( errorCode, "vkCreateDebugReportCallbackEXT" );
}
else{
throw "initDebug: unknown debug extension";
}
return debug;
}
void killDebug( const VkInstance instance, const DebugObjectVariant debug ){
if( debug.tag == DebugObjectType::debugUtils ){
vkDestroyDebugUtilsMessengerEXT( instance, debug.debugUtilsMessenger, nullptr );
}
else if( debug.tag == DebugObjectType::debugReport ){
vkDestroyDebugReportCallbackEXT( instance, debug.debugReportCallback, nullptr );
}
else{
throw "initDebug: unknown debug extension";
}
}

View File

@@ -0,0 +1,425 @@
#pragma once
#include <vector>
#include <unordered_map>
#include<cstring>
#include <vulkan/vulkan.h>
void loadInstanceExtensionsCommands( VkInstance instance, const std::vector<const char*>& instanceExtensions );
void unloadInstanceExtensionsCommands( VkInstance instance );
void loadDeviceExtensionsCommands( VkDevice device, const std::vector<const char*>& instanceExtensions );
void unloadDeviceExtensionsCommands( VkDevice device );
void loadPDProps2Commands( VkInstance instance );
void unloadPDProps2Commands( VkInstance instance );
void loadDebugReportCommands( VkInstance instance );
void unloadDebugReportCommands( VkInstance instance );
void loadDebugUtilsCommands( VkInstance instance );
void unloadDebugUtilsCommands( VkInstance instance );
void loadExternalMemoryCapsCommands( VkInstance instance );
void unloadExternalMemoryCapsCommands( VkInstance instance );
void loadExternalMemoryCommands( VkDevice device );
void unloadExternalMemoryCommands( VkDevice device );
#ifdef VK_USE_PLATFORM_WIN32_KHR
void loadExternalMemoryWin32Commands( VkDevice device );
void unloadExternalMemoryWin32Commands( VkDevice device );
#endif
void loadDedicatedAllocationCommands( VkDevice device );
void unloadDedicatedAllocationCommands( VkDevice device );
////////////////////////////////////////////////////////
std::unordered_map< VkInstance, std::vector<const char*> > instanceExtensionsMap;
std::unordered_map< VkPhysicalDevice, VkInstance > physicalDeviceInstanceMap;
void populatePhysicalDeviceInstaceMap( const VkInstance instance ){
const std::vector<VkPhysicalDevice> physicalDevices = enumerate<VkPhysicalDevice>( instance );
for( const auto pd : physicalDevices ) physicalDeviceInstanceMap[pd] = instance;
}
void loadInstanceExtensionsCommands( const VkInstance instance, const std::vector<const char*>& instanceExtensions ){
using std::strcmp;
instanceExtensionsMap[instance] = instanceExtensions;
for( const auto e : instanceExtensions ){
if( strcmp( e, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME ) == 0 ) loadPDProps2Commands( instance );
if( strcmp( e, VK_EXT_DEBUG_REPORT_EXTENSION_NAME ) == 0 ) loadDebugReportCommands( instance );
if( strcmp( e, VK_EXT_DEBUG_UTILS_EXTENSION_NAME ) == 0 ) loadDebugUtilsCommands( instance );
if( strcmp( e, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME ) == 0 ) loadExternalMemoryCapsCommands( instance );
// ...
}
}
void unloadInstanceExtensionsCommands( const VkInstance instance ){
using std::strcmp;
for( const auto e : instanceExtensionsMap.at( instance ) ){
if( strcmp( e, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME ) == 0 ) unloadPDProps2Commands( instance );
if( strcmp( e, VK_EXT_DEBUG_REPORT_EXTENSION_NAME ) == 0 ) unloadDebugReportCommands( instance );
if( strcmp( e, VK_EXT_DEBUG_UTILS_EXTENSION_NAME ) == 0 ) unloadDebugUtilsCommands( instance );
if( strcmp( e, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME ) == 0 ) unloadExternalMemoryCapsCommands( instance );
// ...
}
instanceExtensionsMap.erase( instance );
}
std::unordered_map< VkDevice, std::vector<const char*> > deviceExtensionsMap;
void loadDeviceExtensionsCommands( const VkDevice device, const std::vector<const char*>& deviceExtensions ){
using std::strcmp;
deviceExtensionsMap[device] = deviceExtensions;
for( const auto e : deviceExtensions ){
if( strcmp( e, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME ) == 0 ) loadExternalMemoryCommands( device );
#ifdef VK_USE_PLATFORM_WIN32_KHR
if( strcmp( e, VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME ) == 0 ) loadExternalMemoryWin32Commands( device );
#endif
if( strcmp( e, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME ) == 0 ) loadDedicatedAllocationCommands( device );
// ...
}
}
void unloadDeviceExtensionsCommands( const VkDevice device ){
using std::strcmp;
for( const auto e : deviceExtensionsMap.at( device ) ){
if( strcmp( e, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME ) == 0 ) unloadExternalMemoryCommands( device );
#ifdef VK_USE_PLATFORM_WIN32_KHR
if( strcmp( e, VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME ) == 0 ) unloadExternalMemoryWin32Commands( device );
#endif
if( strcmp( e, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME ) == 0 ) unloadDedicatedAllocationCommands( device );
// ...
}
deviceExtensionsMap.erase( device );
}
// VK_KHR_get_physical_device_properties2
///////////////////////////////////////////
std::unordered_map< VkInstance, PFN_vkGetPhysicalDeviceFeatures2KHR > GetPhysicalDeviceFeatures2KHRDispatchTable;
std::unordered_map< VkInstance, PFN_vkGetPhysicalDeviceProperties2KHR > GetPhysicalDeviceProperties2KHRDispatchTable;
std::unordered_map< VkInstance, PFN_vkGetPhysicalDeviceFormatProperties2KHR > GetPhysicalDeviceFormatProperties2KHRDispatchTable;
std::unordered_map< VkInstance, PFN_vkGetPhysicalDeviceImageFormatProperties2KHR > GetPhysicalDeviceImageFormatProperties2KHRDispatchTable;
std::unordered_map< VkInstance, PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR > GetPhysicalDeviceQueueFamilyProperties2KHRDispatchTable;
std::unordered_map< VkInstance, PFN_vkGetPhysicalDeviceMemoryProperties2KHR > GetPhysicalDeviceMemoryProperties2KHRDispatchTable;
std::unordered_map< VkInstance, PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR > GetPhysicalDeviceSparseImageFormatProperties2KHRDispatchTable;
void loadPDProps2Commands( VkInstance instance ){
populatePhysicalDeviceInstaceMap( instance );
PFN_vkVoidFunction temp_fp;
temp_fp = vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceFeatures2KHR" );
if( !temp_fp ) throw "Failed to load vkGetPhysicalDeviceFeatures2KHR"; // check shouldn't be necessary (based on spec)
GetPhysicalDeviceFeatures2KHRDispatchTable[instance] = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>( temp_fp );
temp_fp = vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceProperties2KHR" );
if( !temp_fp ) throw "Failed to load vkGetPhysicalDeviceProperties2KHR"; // check shouldn't be necessary (based on spec)
GetPhysicalDeviceProperties2KHRDispatchTable[instance] = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>( temp_fp );
temp_fp = vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceFormatProperties2KHR" );
if( !temp_fp ) throw "Failed to load vkGetPhysicalDeviceFormatProperties2KHR"; // check shouldn't be necessary (based on spec)
GetPhysicalDeviceFormatProperties2KHRDispatchTable[instance] = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2KHR>( temp_fp );
temp_fp = vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceImageFormatProperties2KHR" );
if( !temp_fp ) throw "Failed to load vkGetPhysicalDeviceImageFormatProperties2KHR"; // check shouldn't be necessary (based on spec)
GetPhysicalDeviceImageFormatProperties2KHRDispatchTable[instance] = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2KHR>( temp_fp );
temp_fp = vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR" );
if( !temp_fp ) throw "Failed to load vkGetPhysicalDeviceQueueFamilyProperties2KHR"; // check shouldn't be necessary (based on spec)
GetPhysicalDeviceQueueFamilyProperties2KHRDispatchTable[instance] = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR>( temp_fp );
temp_fp = vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceMemoryProperties2KHR" );
if( !temp_fp ) throw "Failed to load vkGetPhysicalDeviceMemoryProperties2KHR"; // check shouldn't be necessary (based on spec)
GetPhysicalDeviceMemoryProperties2KHRDispatchTable[instance] = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties2KHR>( temp_fp );
temp_fp = vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR" );
if( !temp_fp ) throw "Failed to load vkGetPhysicalDeviceSparseImageFormatProperties2KHR"; // check shouldn't be necessary (based on spec)
GetPhysicalDeviceSparseImageFormatProperties2KHRDispatchTable[instance] = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR>( temp_fp );
}
void unloadPDProps2Commands( VkInstance instance ){
GetPhysicalDeviceFeatures2KHRDispatchTable.erase( instance );
GetPhysicalDeviceProperties2KHRDispatchTable.erase( instance );
GetPhysicalDeviceFormatProperties2KHRDispatchTable.erase( instance );
GetPhysicalDeviceImageFormatProperties2KHRDispatchTable.erase( instance );
GetPhysicalDeviceQueueFamilyProperties2KHRDispatchTable.erase( instance );
GetPhysicalDeviceMemoryProperties2KHRDispatchTable.erase( instance );
GetPhysicalDeviceSparseImageFormatProperties2KHRDispatchTable.erase( instance );
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR( VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures ){
const VkInstance instance = physicalDeviceInstanceMap.at( physicalDevice );
auto dispatched_cmd = GetPhysicalDeviceFeatures2KHRDispatchTable.at( instance );
return dispatched_cmd( physicalDevice, pFeatures );
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2KHR( VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties ){
const VkInstance instance = physicalDeviceInstanceMap.at( physicalDevice );
auto dispatched_cmd = GetPhysicalDeviceProperties2KHRDispatchTable.at( instance );
return dispatched_cmd( physicalDevice, pProperties );
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2KHR( VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties ){
const VkInstance instance = physicalDeviceInstanceMap.at( physicalDevice );
auto dispatched_cmd = GetPhysicalDeviceFormatProperties2KHRDispatchTable.at( instance );
return dispatched_cmd( physicalDevice, format, pFormatProperties );
}
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2KHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties ){
const VkInstance instance = physicalDeviceInstanceMap.at( physicalDevice );
auto dispatched_cmd = GetPhysicalDeviceImageFormatProperties2KHRDispatchTable.at( instance );
return dispatched_cmd( physicalDevice, pImageFormatInfo, pImageFormatProperties );
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2KHR( VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties ){
const VkInstance instance = physicalDeviceInstanceMap.at( physicalDevice );
auto dispatched_cmd = GetPhysicalDeviceQueueFamilyProperties2KHRDispatchTable.at( instance );
return dispatched_cmd( physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties );
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2KHR( VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties ){
const VkInstance instance = physicalDeviceInstanceMap.at( physicalDevice );
auto dispatched_cmd = GetPhysicalDeviceMemoryProperties2KHRDispatchTable.at( instance );
return dispatched_cmd( physicalDevice, pMemoryProperties );
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties ){
const VkInstance instance = physicalDeviceInstanceMap.at( physicalDevice );
auto dispatched_cmd = GetPhysicalDeviceSparseImageFormatProperties2KHRDispatchTable.at( instance );
return dispatched_cmd( physicalDevice, pFormatInfo, pPropertyCount, pProperties );
}
// VK_EXT_debug_report
//////////////////////////////////
std::unordered_map< VkInstance, PFN_vkCreateDebugReportCallbackEXT > CreateDebugReportCallbackEXTDispatchTable;
std::unordered_map< VkInstance, PFN_vkDestroyDebugReportCallbackEXT > DestroyDebugReportCallbackEXTDispatchTable;
std::unordered_map< VkInstance, PFN_vkDebugReportMessageEXT > DebugReportMessageEXTDispatchTable;
void loadDebugReportCommands( VkInstance instance ){
PFN_vkVoidFunction temp_fp;
temp_fp = vkGetInstanceProcAddr( instance, "vkCreateDebugReportCallbackEXT" );
if( !temp_fp ) throw "Failed to load vkCreateDebugReportCallbackEXT"; // check shouldn't be necessary (based on spec)
CreateDebugReportCallbackEXTDispatchTable[instance] = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>( temp_fp );
temp_fp = vkGetInstanceProcAddr( instance, "vkDestroyDebugReportCallbackEXT" );
if( !temp_fp ) throw "Failed to load vkDestroyDebugReportCallbackEXT"; // check shouldn't be necessary (based on spec)
DestroyDebugReportCallbackEXTDispatchTable[instance] = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>( temp_fp );
temp_fp = vkGetInstanceProcAddr( instance, "vkDebugReportMessageEXT" );
if( !temp_fp ) throw "Failed to load vkDebugReportMessageEXT"; // check shouldn't be necessary (based on spec)
DebugReportMessageEXTDispatchTable[instance] = reinterpret_cast<PFN_vkDebugReportMessageEXT>( temp_fp );
}
void unloadDebugReportCommands( VkInstance instance ){
CreateDebugReportCallbackEXTDispatchTable.erase( instance );
DestroyDebugReportCallbackEXTDispatchTable.erase( instance );
DebugReportMessageEXTDispatchTable.erase( instance );
}
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
VkInstance instance,
const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDebugReportCallbackEXT* pCallback
){
auto dispatched_cmd = CreateDebugReportCallbackEXTDispatchTable.at( instance );
return dispatched_cmd( instance, pCreateInfo, pAllocator, pCallback );
}
VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(
VkInstance instance,
VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks* pAllocator
){
auto dispatched_cmd = DestroyDebugReportCallbackEXTDispatchTable.at( instance );
return dispatched_cmd( instance, callback, pAllocator );
}
VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(
VkInstance instance,
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object,
size_t location,
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage
){
auto dispatched_cmd = DebugReportMessageEXTDispatchTable.at( instance );
return dispatched_cmd( instance, flags, objectType, object, location, messageCode, pLayerPrefix, pMessage );
}
// VK_EXT_debug_utils
//////////////////////////////////
std::unordered_map< VkInstance, PFN_vkCreateDebugUtilsMessengerEXT > CreateDebugUtilsMessengerEXTDispatchTable;
std::unordered_map< VkInstance, PFN_vkDestroyDebugUtilsMessengerEXT > DestroyDebugUtilsMessengerEXTDispatchTable;
std::unordered_map< VkInstance, PFN_vkSubmitDebugUtilsMessageEXT > SubmitDebugUtilsMessageEXTDispatchTable;
void loadDebugUtilsCommands( VkInstance instance ){
PFN_vkVoidFunction temp_fp;
temp_fp = vkGetInstanceProcAddr( instance, "vkCreateDebugUtilsMessengerEXT" );
if( !temp_fp ) throw "Failed to load vkCreateDebugUtilsMessengerEXT"; // check shouldn't be necessary (based on spec)
CreateDebugUtilsMessengerEXTDispatchTable[instance] = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>( temp_fp );
temp_fp = vkGetInstanceProcAddr( instance, "vkDestroyDebugUtilsMessengerEXT" );
if( !temp_fp ) throw "Failed to load vkDestroyDebugUtilsMessengerEXT"; // check shouldn't be necessary (based on spec)
DestroyDebugUtilsMessengerEXTDispatchTable[instance] = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>( temp_fp );
temp_fp = vkGetInstanceProcAddr( instance, "vkSubmitDebugUtilsMessageEXT" );
if( !temp_fp ) throw "Failed to load vkSubmitDebugUtilsMessageEXT"; // check shouldn't be necessary (based on spec)
SubmitDebugUtilsMessageEXTDispatchTable[instance] = reinterpret_cast<PFN_vkSubmitDebugUtilsMessageEXT>( temp_fp );
}
void unloadDebugUtilsCommands( VkInstance instance ){
CreateDebugUtilsMessengerEXTDispatchTable.erase( instance );
DestroyDebugUtilsMessengerEXTDispatchTable.erase( instance );
SubmitDebugUtilsMessageEXTDispatchTable.erase( instance );
}
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT(
VkInstance instance,
const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDebugUtilsMessengerEXT* pMessenger
){
auto dispatched_cmd = CreateDebugUtilsMessengerEXTDispatchTable.at( instance );
return dispatched_cmd( instance, pCreateInfo, pAllocator, pMessenger );
}
VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT(
VkInstance instance,
VkDebugUtilsMessengerEXT messenger,
const VkAllocationCallbacks* pAllocator
){
auto dispatched_cmd = DestroyDebugUtilsMessengerEXTDispatchTable.at( instance );
return dispatched_cmd( instance, messenger, pAllocator );
}
VKAPI_ATTR void VKAPI_CALL vkSubmitDebugUtilsMessageEXT(
VkInstance instance,
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData
){
auto dispatched_cmd = SubmitDebugUtilsMessageEXTDispatchTable.at( instance );
return dispatched_cmd( instance, messageSeverity, messageTypes, pCallbackData );
}
// VK_KHR_external_memory_capabilities
///////////////////////////////////////////
std::unordered_map< VkInstance, PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR > GetPhysicalDeviceExternalBufferPropertiesKHRDispatchTable;
void loadExternalMemoryCapsCommands( VkInstance instance ){
populatePhysicalDeviceInstaceMap( instance );
PFN_vkVoidFunction temp_fp;
temp_fp = vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceExternalBufferPropertiesKHR" );
if( !temp_fp ) throw "Failed to load vkGetPhysicalDeviceExternalBufferPropertiesKHR"; // check shouldn't be necessary (based on spec)
GetPhysicalDeviceExternalBufferPropertiesKHRDispatchTable[instance] = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR>( temp_fp );
}
void unloadExternalMemoryCapsCommands( VkInstance instance ){
GetPhysicalDeviceExternalBufferPropertiesKHRDispatchTable.erase( instance );
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferPropertiesKHR(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
VkExternalBufferProperties* pExternalBufferProperties
){
const VkInstance instance = physicalDeviceInstanceMap.at( physicalDevice );
auto dispatched_cmd = GetPhysicalDeviceExternalBufferPropertiesKHRDispatchTable.at( instance );
return dispatched_cmd( physicalDevice, pExternalBufferInfo, pExternalBufferProperties );
}
// VK_KHR_external_memory
///////////////////////////////////////////
void loadExternalMemoryCommands( VkDevice ){
// no commands
}
void unloadExternalMemoryCommands( VkDevice ){
// no commands
}
#ifdef VK_USE_PLATFORM_WIN32_KHR
// VK_KHR_external_memory_win32
///////////////////////////////////////////
std::unordered_map< VkDevice, PFN_vkGetMemoryWin32HandleKHR > GetMemoryWin32HandleKHRDispatchTable;
std::unordered_map< VkDevice, PFN_vkGetMemoryWin32HandlePropertiesKHR > GetMemoryWin32HandlePropertiesKHRDispatchTable;
void loadExternalMemoryWin32Commands( VkDevice device ){
PFN_vkVoidFunction temp_fp;
temp_fp = vkGetDeviceProcAddr( device, "vkGetMemoryWin32HandleKHR" );
if( !temp_fp ) throw "Failed to load vkGetMemoryWin32HandleKHR"; // check shouldn't be necessary (based on spec)
GetMemoryWin32HandleKHRDispatchTable[device] = reinterpret_cast<PFN_vkGetMemoryWin32HandleKHR>( temp_fp );
temp_fp = vkGetDeviceProcAddr( device, "vkGetMemoryWin32HandlePropertiesKHR" );
if( !temp_fp ) throw "Failed to load vkGetMemoryWin32HandlePropertiesKHR"; // check shouldn't be necessary (based on spec)
GetMemoryWin32HandlePropertiesKHRDispatchTable[device] = reinterpret_cast<PFN_vkGetMemoryWin32HandlePropertiesKHR>( temp_fp );
}
void unloadExternalMemoryWin32Commands( VkDevice device ){
GetMemoryWin32HandleKHRDispatchTable.erase( device );
GetMemoryWin32HandlePropertiesKHRDispatchTable.erase( device );
}
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleKHR(
VkDevice device,
const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo,
HANDLE* pHandle
){
auto dispatched_cmd = GetMemoryWin32HandleKHRDispatchTable.at( device );
return dispatched_cmd( device, pGetWin32HandleInfo, pHandle );
}
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
HANDLE handle,
VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties
){
auto dispatched_cmd = GetMemoryWin32HandlePropertiesKHRDispatchTable.at( device );
return dispatched_cmd( device, handleType, handle, pMemoryWin32HandleProperties );
}
#endif
// VK_KHR_dedicated_allocation
///////////////////////////////////////////
void loadDedicatedAllocationCommands( VkDevice ){
// no commands
}
void unloadDedicatedAllocationCommands( VkDevice ){
// no commands
}

View File

@@ -0,0 +1,274 @@
// Introspection for Vulkan enums -- mostly to_string
#pragma once
#include <string>
#include <sstream>
#include <vulkan/vulkan.h>
template <typename PHANDLE_T>
inline uint64_t handleToUint64(const PHANDLE_T *h) { return reinterpret_cast<uint64_t>(h); }
inline uint64_t handleToUint64(const uint64_t h) { return h; }
const char* to_string( const VkResult r ){
switch( r ){
case VK_SUCCESS: return "VK_SUCCESS";
case VK_NOT_READY: return "VK_NOT_READY";
case VK_TIMEOUT: return "VK_TIMEOUT";
case VK_EVENT_SET: return "VK_EVENT_SET";
case VK_EVENT_RESET: return "VK_EVENT_RESET";
case VK_INCOMPLETE: return "VK_INCOMPLETE";
case VK_ERROR_OUT_OF_HOST_MEMORY: return "VK_ERROR_OUT_OF_HOST_MEMORY";
case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
case VK_ERROR_INITIALIZATION_FAILED: return "VK_ERROR_INITIALIZATION_FAILED";
case VK_ERROR_DEVICE_LOST: return "VK_ERROR_DEVICE_LOST";
case VK_ERROR_MEMORY_MAP_FAILED: return "VK_ERROR_MEMORY_MAP_FAILED";
case VK_ERROR_LAYER_NOT_PRESENT: return "VK_ERROR_LAYER_NOT_PRESENT";
case VK_ERROR_EXTENSION_NOT_PRESENT: return "VK_ERROR_EXTENSION_NOT_PRESENT";
case VK_ERROR_FEATURE_NOT_PRESENT: return "VK_ERROR_FEATURE_NOT_PRESENT";
case VK_ERROR_INCOMPATIBLE_DRIVER: return "VK_ERROR_INCOMPATIBLE_DRIVER";
case VK_ERROR_TOO_MANY_OBJECTS: return "VK_ERROR_TOO_MANY_OBJECTS";
case VK_ERROR_FORMAT_NOT_SUPPORTED: return "VK_ERROR_FORMAT_NOT_SUPPORTED";
case VK_ERROR_FRAGMENTED_POOL: return "VK_ERROR_FRAGMENTED_POOL";
case VK_ERROR_UNKNOWN: return "VK_ERROR_UNKNOWN";
case VK_ERROR_OUT_OF_POOL_MEMORY: return "VK_ERROR_OUT_OF_POOL_MEMORY";
case VK_ERROR_INVALID_EXTERNAL_HANDLE: return "VK_ERROR_INVALID_EXTERNAL_HANDLE";
case VK_ERROR_FRAGMENTATION: return "VK_ERROR_FRAGMENTATION";
case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS";
case VK_ERROR_SURFACE_LOST_KHR: return "VK_ERROR_SURFACE_LOST_KHR";
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
case VK_SUBOPTIMAL_KHR: return "VK_SUBOPTIMAL_KHR";
case VK_ERROR_OUT_OF_DATE_KHR: return "VK_ERROR_OUT_OF_DATE_KHR";
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
case VK_ERROR_VALIDATION_FAILED_EXT: return "VK_ERROR_VALIDATION_FAILED_EXT";
case VK_ERROR_INVALID_SHADER_NV: return "VK_ERROR_INVALID_SHADER_NV";
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
case VK_ERROR_NOT_PERMITTED_EXT: return "VK_ERROR_NOT_PERMITTED_EXT";
case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
case VK_THREAD_IDLE_KHR: return "VK_THREAD_IDLE_KHR";
case VK_THREAD_DONE_KHR: return "VK_THREAD_DONE_KHR";
case VK_OPERATION_DEFERRED_KHR: return "VK_OPERATION_DEFERRED_KHR";
case VK_OPERATION_NOT_DEFERRED_KHR: return "VK_OPERATION_NOT_DEFERRED_KHR";
case VK_PIPELINE_COMPILE_REQUIRED_EXT: return "VK_PIPELINE_COMPILE_REQUIRED_EXT";
default: return "unrecognized VkResult code";
}
}
std::string to_string( const VkDebugReportObjectTypeEXT o ){
switch( o ){
case VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT: return "unknown";
case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return "Instance";
case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: return "PhysicalDevice";
case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return "Device";
case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return "Queue";
case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return "Semaphore";
case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return "CommandBuffer";
case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return "Fence";
case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return "DeviceMemory";
case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return "Buffer";
case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return "Image";
case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return "Event";
case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return "QueryPool";
case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return "BufferView";
case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return "ImageView";
case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return "ShaderModule";
case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return "PipelineCache";
case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: return "PipelineLayout";
case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return "RenderPass";
case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return "Pipeline";
case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: return "DescriptorSetLayout";
case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return "Sampler";
case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: return "DescriptorPool";
case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return "DescriptorSet";
case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return "Framebuffer";
case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return "Command pool";
case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return "SurfaceKHR";
case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return "SwapchainKHR";
case VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT: return "DebugReportCallbackEXT";
case VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT: return "DisplayKHR";
case VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT: return "DisplayModeKHR";
case VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT: return "ValidationCacheEXT";
case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT: return "SamplerYcbcrConversion";
case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT: return "DescriptorUpdateTemplate";
case VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT: return "AccelerationStructureKHR";
case VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT: return "AccelerationStructureNV";
default: return "unrecognized type";
}
}
std::string to_string( const VkObjectType o ){
switch( o ){
case VK_OBJECT_TYPE_UNKNOWN: return "unknown";
case VK_OBJECT_TYPE_INSTANCE: return "Instance";
case VK_OBJECT_TYPE_PHYSICAL_DEVICE: return "PhysicalDevice";
case VK_OBJECT_TYPE_DEVICE: return "Device";
case VK_OBJECT_TYPE_QUEUE: return "Queue";
case VK_OBJECT_TYPE_SEMAPHORE: return "Semaphore";
case VK_OBJECT_TYPE_COMMAND_BUFFER: return "CommandBuffer";
case VK_OBJECT_TYPE_FENCE: return "Fence";
case VK_OBJECT_TYPE_DEVICE_MEMORY: return "DeviceMemory";
case VK_OBJECT_TYPE_BUFFER: return "Buffer";
case VK_OBJECT_TYPE_IMAGE: return "Image";
case VK_OBJECT_TYPE_EVENT: return "Event";
case VK_OBJECT_TYPE_QUERY_POOL: return "QueryPool";
case VK_OBJECT_TYPE_BUFFER_VIEW: return "BufferView";
case VK_OBJECT_TYPE_IMAGE_VIEW: return "ImageView";
case VK_OBJECT_TYPE_SHADER_MODULE: return "ShaderModule";
case VK_OBJECT_TYPE_PIPELINE_CACHE: return "PipelineCache";
case VK_OBJECT_TYPE_PIPELINE_LAYOUT: return "PipelineLayout";
case VK_OBJECT_TYPE_RENDER_PASS: return "RenderPass";
case VK_OBJECT_TYPE_PIPELINE: return "Pipeline";
case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT: return "DescriptorSetLayout";
case VK_OBJECT_TYPE_SAMPLER: return "Sampler";
case VK_OBJECT_TYPE_DESCRIPTOR_POOL: return "DescriptorPool";
case VK_OBJECT_TYPE_DESCRIPTOR_SET: return "DescriptorSet";
case VK_OBJECT_TYPE_FRAMEBUFFER: return "Framebuffer";
case VK_OBJECT_TYPE_COMMAND_POOL: return "Command pool";
case VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION: return "SamplerYcbcrConversion";
case VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE: return "DescriptorUpdateTemplateKHR";
case VK_OBJECT_TYPE_SURFACE_KHR: return "SurfaceKHR";
case VK_OBJECT_TYPE_SWAPCHAIN_KHR: return "SwapchainKHR";
case VK_OBJECT_TYPE_DISPLAY_KHR: return "DisplayKHR";
case VK_OBJECT_TYPE_DISPLAY_MODE_KHR: return "DisplayModeKHR";
case VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT: return "DebugReportCallbackEXT";
#ifdef VK_ENABLE_BETA_EXTENSIONS
case VK_OBJECT_TYPE_VIDEO_SESSION_KHR: return "VideoSessionKHR";
case VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR: return "VideoSessionParametersKHR";
#endif
case VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT: return "DebugUtilsMessengerEXT";
case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR: return "AccelerationStructureKHR";
case VK_OBJECT_TYPE_VALIDATION_CACHE_EXT: return "ValidationCacheEXT";
case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV: return "AccelerationStructureNV";
case VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL: return "PerformanceConfigurationINTEL";
case VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR: return "DeferredOperationKHR";
case VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV: return "IndirectCommandsLayoutNV";
case VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT: return "PrivateDataSlotEXT";
default: return "unrecognized type";
}
}
std::string dbrflags_to_string( VkDebugReportFlagsEXT msgFlags ){
std::string res;
bool first = true;
if( msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT ){
if( !first ) res += " | ";
res += "ERROR";
first = false;
}
if( msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT ){
if( !first ) res += " | ";
res += "WARNING";
first = false;
}
if( msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT ){
if( !first ) res += " | ";
res += "PERFORMANCE";
first = false;
}
if( msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT ){
if( !first ) res += " | ";
res += "Info";
first = false;
}
if( msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT ){
if( !first ) res += " | ";
res += "Debug";
first = false;
}
VkDebugReportFlagsEXT known = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;
if( msgFlags & ~known ){
if( !first ) res += " | ";
res += "UNRECOGNIZED_FLAG";
first = false;
}
return res;
}
std::string dbuseverity_to_string( const VkDebugUtilsMessageSeverityFlagsEXT debugSeverity ){
std::string res;
bool first = true;
if( debugSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT ){
if( !first ) res += " | ";
res += "ERROR";
first = false;
}
if( debugSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT ){
if( !first ) res += " | ";
res += "WARNING";
first = false;
}
if( debugSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT ){
if( !first ) res += " | ";
res += "Info";
first = false;
}
if( debugSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT ){
if( !first ) res += " | ";
res += "Verbose";
first = false;
}
VkDebugUtilsMessageSeverityFlagsEXT known = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
if( debugSeverity & ~known ){
if( !first ) res += " | ";
res += "UNRECOGNIZED_FLAG";
first = false;
}
return res;
}
std::string to_string( const VkDebugUtilsMessageSeverityFlagBitsEXT debugSeverity ){
return dbuseverity_to_string( debugSeverity );
}
std::string dbutype_to_string( const VkDebugUtilsMessageTypeFlagsEXT debugType ){
std::string res;
bool first = true;
if( debugType & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT ){
if( !first ) res += " | ";
res += "GENERAL";
first = false;
}
if( debugType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT ){
if( !first ) res += " | ";
res += "VALIDATION";
first = false;
}
if( debugType & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT ){
if( !first ) res += " | ";
res += "PERFORMANCE";
first = false;
}
VkDebugUtilsMessageSeverityFlagsEXT known = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
if( debugType & ~known ){
if( !first ) res += " | ";
res += "UNRECOGNIZED_FLAG";
first = false;
}
return res;
}
std::string to_string_hex( const uint64_t n ){
std::stringstream ss;
ss << std::hex << std::noshowbase << std::uppercase << n;
return "0x" + ss.str();
}

View File

@@ -1,7 +1,7 @@
#include "inferno.hpp"
#include <version.hpp>
#include <graphics.hpp>
#include <version.hpp>
// #include "gui/layout.hpp"
// #include "renderer/renderer.hpp"
// #include "scene/scene.hpp"
@@ -21,6 +21,7 @@
#include <iostream>
#include <memory>
#include <numeric>
#include <set>
namespace inferno {
@@ -83,13 +84,14 @@ InfernoApp* inferno_create()
InfernoApp* app = new InfernoApp;
// app->Input = new InfernoInput;
// app->Scene = scene::scene_create();
// app->MainTimer = inferno_timer_create();
//
app->MainTimer = inferno_timer_create();
// graphics::camera_set_position(app->Scene->Camera, { 0.0f, 1.0f, 3.1f });
//
// // Create window
graphics::window_create("Inferno v" INFERNO_VERSION, 1280, 720);
//
// // setup the scene
// scene::Material* basicMaterial = new scene::Material("basic");
// graphics::Shader* basicShader = graphics::shader_create();
@@ -225,106 +227,105 @@ bool inferno_pre(InfernoApp* app)
void inferno_end(InfernoApp* app)
{
}
int inferno_run(InfernoApp* app)
{
while (true) {
// inferno_timer_start(app->MainTimer);
// if (!inferno_pre(app))
// break;
//
// if (glm::length(app->Input->MouseDelta) > 0.0f)
// graphics::camera_mouse_move(app->Scene->Camera, app->Input->MouseDelta);
// if (app->Input->MovementDelta != 0b00000000)
// graphics::camera_move(app->Scene->Camera, app->Input->MovementDelta);
//
// // Menu Bar
// static bool showPreview = true;
// static bool showRenderSettings = true;
// static bool showDemoWindow = false;
// if (ImGui::BeginMenuBar()) {
// if (ImGui::BeginMenu("Menu")) {
// ImGui::EndMenu();
// }
// if (ImGui::BeginMenu("View")) {
// ImGui::Checkbox("Show Preview", &showPreview);
// ImGui::SameLine();
// inferno_gui_help_marker("Show the preview window");
// ImGui::Checkbox("Show Settings", &showRenderSettings);
// ImGui::SameLine();
// inferno_gui_help_marker("Show the Inferno HART settings window");
// ImGui::Checkbox("Show Demo", &showDemoWindow);
//
// ImGui::EndMenu();
// }
// ImGui::EndMenuBar();
// }
//
// if (showRenderSettings && ImGui::Begin("Inferno HART")) {
// if (ImGui::TreeNode("Camera")) {
// graphics::Camera* camera = scene::scene_get_camera(app->Scene);
// graphics::camera_draw_ui(camera);
// ImGui::TreePop();
// }
// if (ImGui::TreeNode("Preview Render")) {
// ImGui::Checkbox("Show Preview", &showPreview);
// graphics::preview_draw_ui(app->PreviewRenderer);
// if (ImGui::TreeNode("Debug Overlay")) {
// graphics::debug_draw_ui();
// ImGui::TreePop();
// }
// ImGui::TreePop();
// }
// if (ImGui::TreeNode("RayTraced Render")) {
// graphics::rayr_draw_ui(app->RayRenderer);
// ImGui::TreePop();
// }
// ImGui::End();
// }
//
// if (showPreview && ImGui::Begin("Preview", nullptr, ImGuiWindowFlags_NoScrollbar)) {
// if (ImGui::IsWindowHovered()) {
// inferno_move_input(app, inferno_timer_get_time(app->MainTimer));
// } else {
// inferno_stop_move_input(app);
// }
//
// graphics::camera_raster_set_viewport(scene::scene_get_camera(app->Scene),
// { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y });
// graphics::preview_set_viewport(app->PreviewRenderer, app->Scene->Camera);
//
// graphics::preview_draw(app->PreviewRenderer, app->Scene);
// graphics::debug_draw_to_target(app->Scene);
//
// ImTextureID texture = (ImTextureID)graphics::preview_get_rendered_texture(app->PreviewRenderer);
// ImGui::Image(
// texture,
// { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y },
// ImVec2(0, 1), ImVec2(1, 0));
//
// ImGui::End();
// }
//
// if (ImGui::Begin("Render")) {
// graphics::rayr_draw(app->RayRenderer);
//
// ImTextureID texture = (ImTextureID)graphics::rayr_get_rendered_texture(app->RayRenderer);
// ImGui::Image(
// texture,
// { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y },
// ImVec2(0, 1), ImVec2(1, 0));
// ImGui::End();
// }
//
// if (showDemoWindow) {
// ImGui::ShowDemoWindow();
// }
//
// inferno_timer_start(app->MainTimer);
// if (!inferno_pre(app))
// break;
//
// if (glm::length(app->Input->MouseDelta) > 0.0f)
// graphics::camera_mouse_move(app->Scene->Camera, app->Input->MouseDelta);
// if (app->Input->MovementDelta != 0b00000000)
// graphics::camera_move(app->Scene->Camera, app->Input->MovementDelta);
//
// // Menu Bar
// static bool showPreview = true;
// static bool showRenderSettings = true;
// static bool showDemoWindow = false;
// if (ImGui::BeginMenuBar()) {
// if (ImGui::BeginMenu("Menu")) {
// ImGui::EndMenu();
// }
// if (ImGui::BeginMenu("View")) {
// ImGui::Checkbox("Show Preview", &showPreview);
// ImGui::SameLine();
// inferno_gui_help_marker("Show the preview window");
// ImGui::Checkbox("Show Settings", &showRenderSettings);
// ImGui::SameLine();
// inferno_gui_help_marker("Show the Inferno HART settings window");
// ImGui::Checkbox("Show Demo", &showDemoWindow);
//
// ImGui::EndMenu();
// }
// ImGui::EndMenuBar();
// }
//
// if (showRenderSettings && ImGui::Begin("Inferno HART")) {
// if (ImGui::TreeNode("Camera")) {
// graphics::Camera* camera = scene::scene_get_camera(app->Scene);
// graphics::camera_draw_ui(camera);
// ImGui::TreePop();
// }
// if (ImGui::TreeNode("Preview Render")) {
// ImGui::Checkbox("Show Preview", &showPreview);
// graphics::preview_draw_ui(app->PreviewRenderer);
// if (ImGui::TreeNode("Debug Overlay")) {
// graphics::debug_draw_ui();
// ImGui::TreePop();
// }
// ImGui::TreePop();
// }
// if (ImGui::TreeNode("RayTraced Render")) {
// graphics::rayr_draw_ui(app->RayRenderer);
// ImGui::TreePop();
// }
// ImGui::End();
// }
//
// if (showPreview && ImGui::Begin("Preview", nullptr, ImGuiWindowFlags_NoScrollbar)) {
// if (ImGui::IsWindowHovered()) {
// inferno_move_input(app, inferno_timer_get_time(app->MainTimer));
// } else {
// inferno_stop_move_input(app);
// }
//
// graphics::camera_raster_set_viewport(scene::scene_get_camera(app->Scene),
// { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y });
// graphics::preview_set_viewport(app->PreviewRenderer, app->Scene->Camera);
//
// graphics::preview_draw(app->PreviewRenderer, app->Scene);
// graphics::debug_draw_to_target(app->Scene);
//
// ImTextureID texture = (ImTextureID)graphics::preview_get_rendered_texture(app->PreviewRenderer);
// ImGui::Image(
// texture,
// { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y },
// ImVec2(0, 1), ImVec2(1, 0));
//
// ImGui::End();
// }
//
// if (ImGui::Begin("Render")) {
// graphics::rayr_draw(app->RayRenderer);
//
// ImTextureID texture = (ImTextureID)graphics::rayr_get_rendered_texture(app->RayRenderer);
// ImGui::Image(
// texture,
// { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y },
// ImVec2(0, 1), ImVec2(1, 0));
// ImGui::End();
// }
//
// if (showDemoWindow) {
// ImGui::ShowDemoWindow();
// }
//
graphics::window_render();
inferno_end(app);
// inferno_timer_end(app->MainTimer);
// inferno_timer_end(app->MainTimer);
}
//
return 1;

View File

@@ -2,13 +2,15 @@
#include "gui/style.hpp"
#include <version.hpp>
#include <graphics.hpp>
#include <version.hpp>
#include "yolo/yolo.hpp"
#include <optional>
#include <set>
#include <vector>
#include <vulkan/vulkan_core.h>
namespace inferno::graphics {
@@ -17,9 +19,6 @@ static KeyCallback UserKeyCallback = nullptr;
static int Width, Height;
static GLFWwindow* Window;
static VkInstance VulkanInstance;
static VkPhysicalDevice VulkanPhysicalDevice = VK_NULL_HANDLE;
void glfwKeyCallback(GLFWwindow* window, int key, int scancode,
int action, int mods)
{
@@ -33,40 +32,6 @@ void glfwErrorCallback(int error, const char* description)
yolo::error("[GLFW {}] {}", error, description);
}
struct QueueFamilyIndices {
std::optional<uint32_t> graphicsFamily;
bool isComplete() {
return graphicsFamily.has_value();
}
};
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device)
{
QueueFamilyIndices indices;
uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
int i = 0;
for (const auto& queueFamily : queueFamilies) {
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
indices.graphicsFamily = i;
}
if (indices.isComplete()) {
break;
}
i++;
}
return indices;
}
void setupGLFW(std::string title)
{
glfwSetErrorCallback(glfwErrorCallback);
@@ -84,6 +49,11 @@ void setupGLFW(std::string title)
if (Window == NULL)
throw std::runtime_error("Could not create window");
if (!glfwVulkanSupported()) {
yolo::error("Vulkan not supported");
exit(1);
}
// Vulkan Init
VkApplicationInfo appInfo {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
@@ -99,10 +69,13 @@ void setupGLFW(std::string title)
uint32_t glfwExtCount = 0;
const char** exts = glfwGetRequiredInstanceExtensions(&ext);
// add VK_KHR_xcb_surface to the list of extensions
// TODO: This is a massive fuck off hack - SOLVE IT!!!!
exts[glfwExtCount++] = "VK_KHR_xcb_surface";
instInfo.enabledExtensionCount = glfwExtCount;
instInfo.ppEnabledExtensionNames = exts;
instInfo.enabledLayerCount = 0;
yolo::info("GLFW requested {} extensions: {}", glfwExtCount, exts);
yolo::info("GLFW requested {} extensions: {}", glfwExtCount, exts[0]);
if (vkCreateInstance(&instInfo, nullptr, &VulkanInstance) != VK_SUCCESS) {
yolo::error("Could not create Vulkan instance");
@@ -120,14 +93,45 @@ void setupGLFW(std::string title)
std::vector<VkPhysicalDevice> devices(deviceCount);
vkEnumeratePhysicalDevices(VulkanInstance, &deviceCount, devices.data());
// TODO: We need to do device suitability in a much better way
const std::vector<const char*> deviceExtensions {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
};
for (const auto& device : devices) {
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(device, &deviceProperties);
VkPhysicalDeviceFeatures deviceFeatures;
vkGetPhysicalDeviceFeatures(device, &deviceFeatures);
yolo::info("Found Vulkan device: {}", deviceProperties.deviceName);
if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
&& deviceFeatures.geometryShader) {
const auto& checkDevExtensions = [&]() -> bool {
uint32_t extensionCount;
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
std::set<std::string> requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());
for (const auto& extension : availableExtensions) {
requiredExtensions.erase(extension.extensionName);
}
return requiredExtensions.empty();
};
const auto& isDeviceSuitable
= [&]() -> bool {
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(device, &deviceProperties);
VkPhysicalDeviceFeatures deviceFeatures;
vkGetPhysicalDeviceFeatures(device, &deviceFeatures);
yolo::info("Found Vulkan device: {}", deviceProperties.deviceName);
bool features = deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && deviceFeatures.geometryShader;
QueueFamilyIndices indices = window_get_queue_families(device);
bool extensions = checkDevExtensions();
return indices.isComplete() && extensions && features;
};
if (isDeviceSuitable()) {
VulkanPhysicalDevice = device;
break;
}
@@ -139,19 +143,25 @@ void setupGLFW(std::string title)
}
// Logical Device
QueueFamilyIndices indices = findQueueFamilies(VulkanPhysicalDevice);
VkDeviceQueueCreateInfo queueCreateInfo {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = indices.graphicsFamily.value();
queueCreateInfo.queueCount = 1;
QueueFamilyIndices indices = window_get_queue_families(VulkanPhysicalDevice);
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
std::set<uint32_t> uniqueQueueFamilies = { indices.graphicsFamily.value(), indices.presentFamily.value() };
float queuePriority = 1.0f;
queueCreateInfo.pQueuePriorities = &queuePriority;
for (uint32_t queueFamily : uniqueQueueFamilies) {
VkDeviceQueueCreateInfo queueCreateInfo {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = queueFamily;
queueCreateInfo.queueCount = 1;
queueCreateInfo.pQueuePriorities = &queuePriority;
queueCreateInfos.push_back(queueCreateInfo);
}
VkPhysicalDeviceFeatures deviceFeatures {};
VkDeviceCreateInfo createInfo {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.pQueueCreateInfos = &queueCreateInfo;
createInfo.queueCreateInfoCount = 1;
createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
createInfo.pQueueCreateInfos = queueCreateInfos.data();
createInfo.pEnabledFeatures = &deviceFeatures;
createInfo.enabledExtensionCount = 0;
createInfo.enabledLayerCount = 0;
@@ -161,9 +171,18 @@ void setupGLFW(std::string title)
exit(1);
}
vkGetDeviceQueue(VulkanDevice, indices.graphicsFamily.value(), 0, &VulkanPresentQueue);
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(VulkanPhysicalDevice, &deviceProperties);
yolo::info("Vulkan running on ", deviceProperties.deviceName);
// "Surface" creation
VkResult result = glfwCreateWindowSurface(VulkanInstance, Window, nullptr, &VulkanSurface);
if (result != VK_SUCCESS) {
yolo::error("Could not create Vulkan surface (code: {})", result);
exit(1);
}
}
void setupImGui()
@@ -246,6 +265,8 @@ void window_create(std::string title, int width, int height)
void window_cleanup()
{
vkDestroySurfaceKHR(VulkanInstance, VulkanSurface, nullptr);
vkDestroyInstance(VulkanInstance, nullptr);
vkDestroyDevice(VulkanDevice, nullptr);
shutdownGLFW();
}
@@ -268,6 +289,41 @@ glm::vec2 window_get_size() { return { Width, Height }; }
void window_get_pos(int& x, int& y) { glfwGetWindowPos(Window, &x, &y); }
// VULKAN SPECIFIC
QueueFamilyIndices window_get_queue_families(VkPhysicalDevice device)
{
QueueFamilyIndices indices;
uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
int i = 0;
for (const auto& queueFamily : queueFamilies) {
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
indices.graphicsFamily = i;
}
VkBool32 presentSupport = false;
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, VulkanSurface, &presentSupport);
if (presentSupport) {
indices.presentFamily = i;
}
if (indices.isComplete()) {
break;
}
i++;
}
return indices;
}
// END VULKAN SPECIFIC
GLFWwindow* window_get_glfw_window() { return Window; }
void window_set_mode(WINDOW_MODE mode)

View File

@@ -1,9 +1,10 @@
#pragma once
#include <string>
#include "graphics.hpp"
#include <string>
#include <optional>
#define WINDOW_FLAGS ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoCollapse
namespace inferno::graphics {
@@ -11,13 +12,27 @@ namespace inferno::graphics {
typedef void (*KeyCallback)(int key, int scan, int action, int mod);
typedef void (*MouseCallback)(double x, double y);
static VkInstance VulkanInstance;
static VkPhysicalDevice VulkanPhysicalDevice = VK_NULL_HANDLE;
static VkDevice VulkanDevice;
static VkQueue VulkanPresentQueue;
static VkSurfaceKHR VulkanSurface;
enum WINDOW_MODE {
WIN_MODE_DEFAULT,
WIN_MODE_FPS,
};
struct QueueFamilyIndices {
std::optional<uint32_t> graphicsFamily;
std::optional<uint32_t> presentFamily;
bool isComplete()
{
return graphicsFamily.has_value() && presentFamily.has_value();
}
};
void window_create(std::string title, int width, int height);
void window_cleanup();
@@ -28,6 +43,10 @@ void window_set_pos(int x, int y);
glm::vec2 window_get_size();
void window_get_pos(int& x, int& y);
// VULKAN SPECIFIC
QueueFamilyIndices window_get_queue_families(VkPhysicalDevice device);
// END VULKAN SPECIFIC
GLFWwindow* window_get_glfw_window();
void window_set_mode(WINDOW_MODE mode);