Been stuck with this issue for the past few days. I'm trying to use the Vulkan API's debug layers I've sucessfully fetched the function pointers for the PFN_vkCreateDebugReportCallbackEXT and PFN_vkDestroyDebugReportCallbackEXT.
But when creating the struct to use as an argument for the vkCreateDebugReportCallback I'm having issues with the pfnCallback part of the struct.
Visual studio is giving me this error when trying to compile, and I have tried typecasting it as follows :
dbgReportCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT) debugFunction;
and
dbgReportCreateInfo.pfnCallback = reinterpret_cast<PFN_vkDebugReportCallbackEXT>(debugFunction);
which both cause a memory access violation when the vkCreateDebugReportCallback function is called.
What should work
From the textbook Learning Vulkan and the supplied repository the proper declaration for the PFN_vkDebugReportCallbackEXT pfn part of the struct should be as shown in their repository here.
VKAPI_ATTR VkBool32 VKAPI_CALL debugFunction(
VkFlags msgFlags,
VkDebugReportObjectTypeEXT objType,
uint64_t srcObject,
size_t location,
uint32_t msgCode,
const char * layerPrefix,
const char * msg,
void * userData);
Vulkan Header file
Which is just as is defined in the Vulkan header file, vulkan.h
typdef uint32_t VkBool32;
typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)(
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object,
size_t location,
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage,
void* pUserData);
typedef struct VkDebugReportCallbackCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkDebugReportFlagsEXT flags;
PFN_vkDebugReportCallbackEXT pfnCallback;
void* pUserData;
} VkDebugReportCallbackCreateInfoEXT;
Visual Studio Error
Severity Code Description Project File Line Source Suppression State Error C2440 '=': cannot convert from 'VkBool32 (__cdecl *)(VkDebugReportFlagsEXT,VkDebugReportObjectTypeEXT,uint64_t,std::size_t,uint32_t,const char *,const char *,void *)' to 'PFN_vkDebugReportCallbackEXT' vulkanproject C:\Users\Alec\workspace\cpp\vulkanproject\source\VulkanLayerAndExtension.cpp 287 Build
My code
Full project available in my Github repository
class VulkanLayerAndExtension {
// Some stuff before
VkResult createDebugReportCallback();
void destroyDebugReportCallback();
static VKAPI_ATTR VkBool32 VKAPI_CALL debugFunction(VkDebugReportFlagsEXT msgFlags,
VkDebugReportObjectTypeEXT objType,
uint64_t srcObject,
size_t location,
uint32_t msgCode,
const char * layerPrefix,
const char * msg,
void * userData);
private:
PFN_vkCreateDebugReportCallbackEXT dbgCreateDebugReportCallback;
PFN_vkDestroyDebugReportCallbackEXT dbgDestroyDebugReportCallback;
VkDebugReportCallbackEXT debugReportCallback;
public:
VkDebugReportCallbackCreateInfoEXT dbgReportCreateInfo = {};
// stuff before
VKAPI_ATTR VkBool32 VKAPI_CALL
VulkanLayerAndExtension::debugFunction(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, uint32_t msgCode, const char * layerPrefix, const char * msg, void * userData)
{
std::cout << "[VK_DEBUG_REPORT] ";
if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
std::cout << "ERROR";
}
else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
std::cout << "WARNING";
}
else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
std::cout << "INFORMATION";
}
else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
std::cout << "PERFORMANCE";
}
else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
std::cout << "DEBUG";
}
else {
return VK_FALSE;
}
std::cout << ": [" << layerPrefix << "] Code" << msgCode << ":" << msg << std::endl;
return VK_TRUE;
}
VkResult VulkanLayerAndExtension::createDebugReportCallback()
{
VkResult result;
VulkanApplication * appObj = VulkanApplication::GetInstance();
VkInstance* instance = &appObj->instanceObj.instance;
// Get vkCreateDebugReportCallbackEXT API
dbgCreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT) vkGetInstanceProcAddr(*instance, "vkCreateDebugReportCallbackEXT");
if (!dbgCreateDebugReportCallback) {
std::cout << "Error: GetInstanceProcAddr unable to locate vkCreateDebugReportCallbackEXT function.\n";
return VK_ERROR_INITIALIZATION_FAILED;
}
std::cout << "GetInstanceProcAddr loaded dbgCreateDebugReportCallback function.\n";
// Get vkDestroyDebugReportCallbackEXT API
dbgDestroyDebugReportCallback = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(*instance, "vkDestroyDebugReportCallbackEXT");
if (!dbgDestroyDebugReportCallback) {
std::cout << "Error: GetInstanceProcAddr unable to locate vkDestroyDebugReportCallbackEXT function.\n";
return VK_ERROR_INITIALIZATION_FAILED;
}
std::cout << "GetInstanceProcAddr loaded dbgDestroyDebugReportCallback function.\n";
dbgReportCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
// Type error occurs on this line below
dbgReportCreateInfo.pfnCallback = VulkanLayerAndExtension::debugFunction;
dbgReportCreateInfo.pUserData = NULL;
dbgReportCreateInfo.pNext = NULL;
dbgReportCreateInfo.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT |
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
VK_DEBUG_REPORT_ERROR_BIT_EXT |
VK_DEBUG_REPORT_DEBUG_BIT_EXT;
// Create the debug report callback object
result = dbgCreateDebugReportCallback(*instance, &dbgReportCreateInfo, NULL, &debugReportCallback);
if (result == VK_SUCCESS) {
std::cout << "Debug report callback object created successfully.\n";
}
return result;
}
void VulkanLayerAndExtension::destroyDebugReportCallback()
{
VulkanApplication * appObj = VulkanApplication::GetInstance();
VkInstance & instance = appObj->instanceObj.instance;
if (debugReportCallback) {
dbgDestroyDebugReportCallback(instance, debugReportCallback, NULL);
}
}