device suitability is in a better place now
This commit is contained in:
@@ -66,6 +66,7 @@ else()
|
||||
target_link_libraries(inferno PRIVATE
|
||||
${GLFW3_LIBRARIES}
|
||||
Vulkan::Vulkan
|
||||
libvulkan.so
|
||||
OpenMP::OpenMP_CXX
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -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*>;
|
||||
}
|
||||
|
||||
150
src/graphics/enumeratescheme.hpp
Normal file
150
src/graphics/enumeratescheme.hpp
Normal 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
|
||||
|
||||
203
src/graphics/errorhandling.hpp
Normal file
203
src/graphics/errorhandling.hpp
Normal 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";
|
||||
}
|
||||
}
|
||||
|
||||
425
src/graphics/vulkanextensionloader.hpp
Normal file
425
src/graphics/vulkanextensionloader.hpp
Normal 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
|
||||
}
|
||||
|
||||
274
src/graphics/vulkanintrospection.hpp
Normal file
274
src/graphics/vulkanintrospection.hpp
Normal 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();
|
||||
}
|
||||
|
||||
197
src/inferno.cpp
197
src/inferno.cpp
@@ -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;
|
||||
|
||||
164
src/window.cpp
164
src/window.cpp
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user