#include <vector>
using std::vector;
#include <iostream>
using std::cout; using std::endl;
#include <vulkan/vulkan.h>
#define RESULT_HANDLER( errorCode, source ) if( errorCode ) throw "Fail!"
constexpr VkDebugReportFlagsEXT debugAmount = VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT;
VKAPI_ATTR VkBool32 VKAPI_CALL genericDebugCallback( VkDebugReportFlagsEXT, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char*, const char* pMessage, void* );
VkInstance initInstance( const vector<const char*>& layers = {}, const vector<const char*>& extensions = {} );
void loadDebugReportCommands( VkInstance instance );
VkDebugReportCallbackEXT initDebug( const VkInstance instance );
int main(){
const VkInstance instance = initInstance( {"VK_LAYER_LUNARG_standard_validation"}, {VK_EXT_DEBUG_REPORT_EXTENSION_NAME} );
loadDebugReportCommands( instance );
const VkDebugReportCallbackEXT debug = initDebug( instance );
vkDebugReportMessageEXT( instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 0, "Application", "Hello layer!" ); // send custom msg
vkEnumeratePhysicalDevices( instance, nullptr, nullptr ); // trip VU
vkDestroyDebugReportCallbackEXT( instance, debug, nullptr );
vkDestroyInstance( instance, nullptr );
}
VKAPI_ATTR VkBool32 VKAPI_CALL genericDebugCallback( VkDebugReportFlagsEXT, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char*, const char* pMessage, void* ){
cout << pMessage << endl;
return VK_FALSE; // no abort on misbehaving command
}
VkInstance initInstance( const vector<const char*>& layers, const vector<const char*>& extensions ){
// in effect during vkCreateInstance and vkDestroyInstance duration (because callback object cannot be created without instance)
const VkDebugReportCallbackCreateInfoEXT debugCreateInfo{
VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
nullptr, // pNext
::debugAmount,
::genericDebugCallback,
nullptr // pUserData
};
const VkInstanceCreateInfo instanceInfo{
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
&debugCreateInfo,
0, // flags - reserved for future use
nullptr, // appInfo
static_cast<uint32_t>( layers.size() ),
layers.data(),
static_cast<uint32_t>( extensions.size() ),
extensions.data()
};
VkInstance instance;
const VkResult errorCode = vkCreateInstance( &instanceInfo, nullptr, &instance ); RESULT_HANDLER( errorCode, "vkCreateInstance" );
return instance;
}
PFN_vkCreateDebugReportCallbackEXT fpCreateDebugReportCallbackEXT = nullptr;
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback ){
return fpCreateDebugReportCallbackEXT( instance, pCreateInfo, pAllocator, pCallback );
}
PFN_vkDestroyDebugReportCallbackEXT fpDestroyDebugReportCallbackEXT = nullptr;
VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT( VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator ){
return fpDestroyDebugReportCallbackEXT( instance, callback, pAllocator );
}
PFN_vkDebugReportMessageEXT fpDebugReportMessageEXT = nullptr;
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 ){
return fpDebugReportMessageEXT( instance, flags, objectType, object, location, messageCode, pLayerPrefix, pMessage );
}
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)
fpCreateDebugReportCallbackEXT = 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)
fpDestroyDebugReportCallbackEXT = 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)
fpDebugReportMessageEXT = reinterpret_cast<PFN_vkDebugReportMessageEXT>( temp_fp );
}
VkDebugReportCallbackEXT initDebug( const VkInstance instance ){
const VkDebugReportCallbackCreateInfoEXT debugCreateInfo{
VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
nullptr, // pNext
::debugAmount,
::genericDebugCallback,
nullptr // pUserData
};
VkDebugReportCallbackEXT debug;
const VkResult errorCode = vkCreateDebugReportCallbackEXT( instance, &debugCreateInfo, nullptr, &debug ); RESULT_HANDLER( errorCode, "vkCreateDebugReportCallbackEXT" );
return debug;
}