mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-23 07:31:56 +00:00
Further improve VK extension loading. Switch to VK_EXT_debug_utils (but fallback to VK_EXT_debug_report if only that is available).
This commit is contained in:
parent
014668b9bc
commit
478b0b4278
@ -120,9 +120,6 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) {
|
||||
//#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
// instance_extensions_enabled_.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
||||
//#endif
|
||||
//#if defined(VK_USE_PLATFORM_MIR_KHR)
|
||||
// instance_extensions_enabled_.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME);
|
||||
//#endif
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
if (IsInstanceExtensionAvailable(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME)) {
|
||||
instance_extensions_enabled_.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
@ -131,12 +128,21 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) {
|
||||
#endif
|
||||
|
||||
if (flags_ & VULKAN_FLAG_VALIDATE) {
|
||||
if (IsInstanceExtensionAvailable(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
|
||||
if (IsInstanceExtensionAvailable(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
|
||||
// Enable the validation layers
|
||||
for (size_t i = 0; i < ARRAY_SIZE(validationLayers); i++) {
|
||||
instance_layer_names_.push_back(validationLayers[i]);
|
||||
device_layer_names_.push_back(validationLayers[i]);
|
||||
}
|
||||
instance_extensions_enabled_.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
extensionsLookup_.EXT_debug_utils = true;
|
||||
} else if (IsInstanceExtensionAvailable(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(validationLayers); i++) {
|
||||
instance_layer_names_.push_back(validationLayers[i]);
|
||||
device_layer_names_.push_back(validationLayers[i]);
|
||||
}
|
||||
instance_extensions_enabled_.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
||||
extensionsLookup_.EXT_debug_report = true;
|
||||
} else {
|
||||
ELOG("Validation layer extension not available - not enabling Vulkan validation.");
|
||||
flags_ &= ~VULKAN_FLAG_VALIDATE;
|
||||
@ -195,7 +201,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) {
|
||||
return res;
|
||||
}
|
||||
|
||||
VulkanLoadInstanceFunctions(instance_);
|
||||
VulkanLoadInstanceFunctions(instance_, extensionsLookup_);
|
||||
if (!CheckLayers(instance_layer_properties_, instance_layer_names_)) {
|
||||
WLOG("CheckLayers for instance failed");
|
||||
// init_error_ = "Failed to validate instance layers";
|
||||
@ -604,8 +610,8 @@ VkResult VulkanContext::CreateDevice() {
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
VkDeviceQueueCreateInfo queue_info{ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO };
|
||||
float queue_priorities[1] = { 1.0f };
|
||||
VkDeviceQueueCreateInfo queue_info{VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO};
|
||||
float queue_priorities[1] = {1.0f};
|
||||
queue_info.queueCount = 1;
|
||||
queue_info.pQueuePriorities = queue_priorities;
|
||||
bool found = false;
|
||||
@ -618,12 +624,24 @@ VkResult VulkanContext::CreateDevice() {
|
||||
}
|
||||
assert(found);
|
||||
|
||||
extensionsLookup_.KHR_maintenance1 = EnableDeviceExtension(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
|
||||
extensionsLookup_.KHR_maintenance2 = EnableDeviceExtension(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
|
||||
extensionsLookup_.KHR_maintenance3 = EnableDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
||||
extensionsLookup_.KHR_multiview = EnableDeviceExtension(VK_KHR_MULTIVIEW_EXTENSION_NAME);
|
||||
|
||||
if (EnableDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) {
|
||||
extensionsLookup_.KHR_get_memory_requirements2 = true;
|
||||
extensionsLookup_.KHR_dedicated_allocation = EnableDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
||||
}
|
||||
extensionsLookup_.EXT_external_memory_host = EnableDeviceExtension(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME);
|
||||
extensionsLookup_.KHR_depth_stencil_resolve = EnableDeviceExtension(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME);
|
||||
if (EnableDeviceExtension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
|
||||
if (EnableDeviceExtension(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME)) {
|
||||
extensionsLookup_.EXT_external_memory_host = EnableDeviceExtension(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME);
|
||||
}
|
||||
}
|
||||
if (EnableDeviceExtension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) {
|
||||
extensionsLookup_.KHR_create_renderpass2 = true;
|
||||
extensionsLookup_.KHR_depth_stencil_resolve = EnableDeviceExtension(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME);
|
||||
}
|
||||
extensionsLookup_.EXT_shader_stencil_export = EnableDeviceExtension(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME);
|
||||
|
||||
VkDeviceCreateInfo device_info{ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
|
||||
@ -640,7 +658,7 @@ VkResult VulkanContext::CreateDevice() {
|
||||
init_error_ = "Unable to create Vulkan device";
|
||||
ELOG("Unable to create Vulkan device");
|
||||
} else {
|
||||
VulkanLoadDeviceFunctions(device_);
|
||||
VulkanLoadDeviceFunctions(device_, extensionsLookup_);
|
||||
}
|
||||
ILOG("Device created.\n");
|
||||
VulkanSetAvailable(true);
|
||||
@ -662,7 +680,7 @@ VkResult VulkanContext::InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFun
|
||||
cb.flags = bits;
|
||||
cb.pfnCallback = dbgFunc;
|
||||
cb.pUserData = userdata;
|
||||
VkResult res = dyn_vkCreateDebugReportCallbackEXT(instance_, &cb, nullptr, &msg_callback);
|
||||
VkResult res = vkCreateDebugReportCallbackEXT(instance_, &cb, nullptr, &msg_callback);
|
||||
switch (res) {
|
||||
case VK_SUCCESS:
|
||||
msg_callbacks.push_back(msg_callback);
|
||||
@ -676,12 +694,42 @@ VkResult VulkanContext::InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFun
|
||||
}
|
||||
|
||||
void VulkanContext::DestroyDebugMsgCallback() {
|
||||
if (!extensionsLookup_.EXT_debug_report)
|
||||
return;
|
||||
while (msg_callbacks.size() > 0) {
|
||||
dyn_vkDestroyDebugReportCallbackEXT(instance_, msg_callbacks.back(), nullptr);
|
||||
vkDestroyDebugReportCallbackEXT(instance_, msg_callbacks.back(), nullptr);
|
||||
msg_callbacks.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
VkResult VulkanContext::InitDebugUtilsCallback(PFN_vkDebugUtilsMessengerCallbackEXT callback, int bits, void *userdata) {
|
||||
VkDebugUtilsMessengerCreateInfoEXT callback1{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT};
|
||||
callback1.messageSeverity = bits;
|
||||
callback1.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
callback1.pfnUserCallback = callback;
|
||||
callback1.pUserData = userdata;
|
||||
VkDebugUtilsMessengerEXT messenger;
|
||||
VkResult res = vkCreateDebugUtilsMessengerEXT(instance_, &callback1, nullptr, &messenger);
|
||||
if (res != VK_SUCCESS) {
|
||||
ELOG("Failed to register debug callback with vkCreateDebugUtilsMessengerEXT");
|
||||
// Do error handling for VK_ERROR_OUT_OF_MEMORY
|
||||
} else {
|
||||
ILOG("Debug callback registered with vkCreateDebugUtilsMessengerEXT.");
|
||||
utils_callbacks.push_back(messenger);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void VulkanContext::DestroyDebugUtilsCallback() {
|
||||
if (!extensionsLookup_.EXT_debug_utils)
|
||||
return;
|
||||
while (utils_callbacks.size() > 0) {
|
||||
vkDestroyDebugUtilsMessengerEXT(instance_, utils_callbacks.back(), nullptr);
|
||||
utils_callbacks.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VkResult VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2) {
|
||||
winsys_ = winsys;
|
||||
winsysData1_ = data1;
|
||||
|
@ -101,17 +101,6 @@ private:
|
||||
std::vector<Callback> callbacks_;
|
||||
};
|
||||
|
||||
// For fast extension-enabled checks.
|
||||
struct VulkanDeviceExtensions {
|
||||
bool KHR_get_memory_requirements2;
|
||||
bool KHR_dedicated_allocation;
|
||||
bool EXT_external_memory_host;
|
||||
bool KHR_get_physical_device_properties2;
|
||||
bool KHR_depth_stencil_resolve;
|
||||
bool EXT_shader_stencil_export;
|
||||
// bool EXT_depth_range_unrestricted; // Allows depth outside [0.0, 1.0] in 32-bit float depth buffers.
|
||||
};
|
||||
|
||||
// Useful for debugging on ARM Mali. This eliminates transaction elimination
|
||||
// which can cause artifacts if you get barriers wrong (or if there are driver bugs).
|
||||
// Cost is reduced performance on some GPU architectures.
|
||||
@ -175,7 +164,11 @@ public:
|
||||
|
||||
bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex);
|
||||
|
||||
VkResult InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFunc, int bits, void *userdata = nullptr);
|
||||
VkResult InitDebugUtilsCallback(PFN_vkDebugUtilsMessengerCallbackEXT callback, int bits, void *userdata);
|
||||
void DestroyDebugUtilsCallback();
|
||||
|
||||
// Legacy reporting
|
||||
VkResult InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFunc, int bits, void *userdata);
|
||||
void DestroyDebugMsgCallback();
|
||||
|
||||
VkPhysicalDevice GetPhysicalDevice(int n = 0) const {
|
||||
@ -334,6 +327,7 @@ private:
|
||||
VulkanDeleteList globalDeleteList_;
|
||||
|
||||
std::vector<VkDebugReportCallbackEXT> msg_callbacks;
|
||||
std::vector<VkDebugUtilsMessengerEXT> utils_callbacks;
|
||||
|
||||
VkSwapchainKHR swapchain_ = VK_NULL_HANDLE;
|
||||
VkFormat swapchainFormat_;
|
||||
|
@ -56,7 +56,7 @@ const char *ObjTypeToString(VkDebugReportObjectTypeEXT type) {
|
||||
}
|
||||
}
|
||||
|
||||
VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) {
|
||||
VkBool32 VKAPI_CALL VulkanDebugReportCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) {
|
||||
const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData;
|
||||
std::ostringstream message;
|
||||
|
||||
@ -103,3 +103,60 @@ VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObje
|
||||
// keep that behavior here.
|
||||
return false;
|
||||
}
|
||||
|
||||
VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData) {
|
||||
const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData;
|
||||
std::ostringstream message;
|
||||
|
||||
const char *pMessage = pCallbackData->pMessage;
|
||||
int messageCode = pCallbackData->messageIdNumber;
|
||||
const char *pLayerPrefix = "";
|
||||
// Ignore perf warnings for now. Could log them, so still want them registered.
|
||||
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
|
||||
message << "ERROR(";
|
||||
} else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
|
||||
message << "WARNING(";
|
||||
} else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
|
||||
message << "INFO(";
|
||||
} else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
|
||||
message << "VERBOSE(";
|
||||
}
|
||||
|
||||
if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) {
|
||||
message << "perf";
|
||||
} else if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) {
|
||||
message << "general";
|
||||
} else if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) {
|
||||
message << "validation";
|
||||
}
|
||||
message << ":" << pCallbackData->messageIdNumber << ") " << pMessage << "\n";
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string msg = message.str();
|
||||
OutputDebugStringA(msg.c_str());
|
||||
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
|
||||
if (options->breakOnError && IsDebuggerPresent()) {
|
||||
DebugBreak();
|
||||
}
|
||||
if (options->msgBoxOnError) {
|
||||
MessageBoxA(NULL, pMessage, "Alert", MB_OK);
|
||||
}
|
||||
} else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
|
||||
if (options->breakOnWarning && IsDebuggerPresent() && 0 == (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)) {
|
||||
DebugBreak();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// false indicates that layer should not bail-out of an
|
||||
// API call that had validation failures. This may mean that the
|
||||
// app dies inside the driver due to invalid parameter(s).
|
||||
// That's what would happen without validation layers, so we'll
|
||||
// keep that behavior here.
|
||||
return false;
|
||||
}
|
||||
|
@ -25,4 +25,5 @@ struct VulkanLogOptions {
|
||||
bool msgBoxOnError;
|
||||
};
|
||||
|
||||
VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData);
|
||||
VkBool32 VKAPI_CALL VulkanDebugReportCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData);
|
||||
VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData);
|
||||
|
@ -193,8 +193,16 @@ PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
|
||||
PFN_vkQueuePresentKHR vkQueuePresentKHR;
|
||||
|
||||
// And the DEBUG_REPORT extension. We dynamically load this.
|
||||
PFN_vkCreateDebugReportCallbackEXT dyn_vkCreateDebugReportCallbackEXT;
|
||||
PFN_vkDestroyDebugReportCallbackEXT dyn_vkDestroyDebugReportCallbackEXT;
|
||||
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
|
||||
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
|
||||
|
||||
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
|
||||
PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT;
|
||||
PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT;
|
||||
PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT;
|
||||
PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT;
|
||||
PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT;
|
||||
PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT;
|
||||
|
||||
PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT;
|
||||
PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;
|
||||
@ -262,19 +270,22 @@ bool VulkanMayBeAvailable() {
|
||||
VkApplicationInfo info{ VK_STRUCTURE_TYPE_APPLICATION_INFO };
|
||||
std::vector<VkPhysicalDevice> devices;
|
||||
bool anyGood = false;
|
||||
const char *instanceExtensions[1]{};
|
||||
const char *instanceExtensions[2]{};
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkResult res;
|
||||
uint32_t physicalDeviceCount = 0;
|
||||
uint32_t instanceExtCount = 0;
|
||||
uint32_t instanceExtCount = 1;
|
||||
bool surfaceExtensionFound = false;
|
||||
bool platformSurfaceExtensionFound = false;
|
||||
std::vector<VkExtensionProperties> instanceExts;
|
||||
instanceExtensions[ci.enabledExtensionCount++] = VK_KHR_SURFACE_EXTENSION_NAME;
|
||||
|
||||
#ifdef _WIN32
|
||||
const char * const surfaceExtension = VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
|
||||
const char * const platformSurfaceExtension = VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
|
||||
#elif defined(__ANDROID__)
|
||||
const char *surfaceExtension = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
|
||||
const char *platformSurfaceExtension = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
|
||||
#else
|
||||
const char *surfaceExtension = 0;
|
||||
const char *platformSurfaceExtension = 0;
|
||||
#endif
|
||||
|
||||
if (!localEnumerateInstanceExtensionProperties || !localCreateInstance || !localEnumerate || !localDestroyInstance || !localGetPhysicalDeviceProperties)
|
||||
@ -297,16 +308,18 @@ bool VulkanMayBeAvailable() {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (surfaceExtension) {
|
||||
if (platformSurfaceExtension) {
|
||||
for (auto iter : instanceExts) {
|
||||
if (!strcmp(iter.extensionName, surfaceExtension)) {
|
||||
instanceExtensions[0] = surfaceExtension;
|
||||
ci.enabledExtensionCount = 1;
|
||||
if (!strcmp(iter.extensionName, platformSurfaceExtension)) {
|
||||
instanceExtensions[ci.enabledExtensionCount++] = platformSurfaceExtension;
|
||||
platformSurfaceExtensionFound = true;
|
||||
break;
|
||||
} else if (!strcmp(iter.extensionName, VK_KHR_SURFACE_EXTENSION_NAME)) {
|
||||
surfaceExtensionFound = true;
|
||||
}
|
||||
}
|
||||
if (!ci.enabledExtensionCount) {
|
||||
ELOG("Surface extension not found");
|
||||
if (!platformSurfaceExtensionFound || !surfaceExtensionFound) {
|
||||
ELOG("Platform surface extension not found");
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
@ -411,7 +424,7 @@ bool VulkanLoad() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void VulkanLoadInstanceFunctions(VkInstance instance) {
|
||||
void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensions &enabledExtensions) {
|
||||
// OK, let's use the above functions to get the rest.
|
||||
LOAD_INSTANCE_FUNC(instance, vkDestroyInstance);
|
||||
LOAD_INSTANCE_FUNC(instance, vkEnumeratePhysicalDevices);
|
||||
@ -570,11 +583,26 @@ void VulkanLoadInstanceFunctions(VkInstance instance) {
|
||||
#endif
|
||||
|
||||
LOAD_INSTANCE_FUNC(instance, vkDestroySurfaceKHR);
|
||||
LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceProperties2KHR);
|
||||
LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceFeatures2KHR);
|
||||
|
||||
dyn_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
|
||||
dyn_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
|
||||
if (enabledExtensions.KHR_get_physical_device_properties2) {
|
||||
LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceProperties2KHR);
|
||||
LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceFeatures2KHR);
|
||||
}
|
||||
|
||||
if (enabledExtensions.EXT_debug_report) {
|
||||
LOAD_INSTANCE_FUNC(instance, vkCreateDebugReportCallbackEXT);
|
||||
LOAD_INSTANCE_FUNC(instance, vkDestroyDebugReportCallbackEXT);
|
||||
}
|
||||
|
||||
if (enabledExtensions.EXT_debug_utils) {
|
||||
LOAD_INSTANCE_FUNC(instance, vkCreateDebugUtilsMessengerEXT);
|
||||
LOAD_INSTANCE_FUNC(instance, vkDestroyDebugUtilsMessengerEXT);
|
||||
LOAD_INSTANCE_FUNC(instance, vkCmdBeginDebugUtilsLabelEXT);
|
||||
LOAD_INSTANCE_FUNC(instance, vkCmdEndDebugUtilsLabelEXT);
|
||||
LOAD_INSTANCE_FUNC(instance, vkCmdInsertDebugUtilsLabelEXT);
|
||||
LOAD_INSTANCE_FUNC(instance, vkSetDebugUtilsObjectNameEXT);
|
||||
LOAD_INSTANCE_FUNC(instance, vkSetDebugUtilsObjectTagEXT);
|
||||
}
|
||||
|
||||
WLOG("Vulkan instance functions loaded.");
|
||||
}
|
||||
@ -582,7 +610,7 @@ void VulkanLoadInstanceFunctions(VkInstance instance) {
|
||||
// On some implementations, loading functions (that have Device as their first parameter) via vkGetDeviceProcAddr may
|
||||
// increase performance - but then these function pointers will only work on that specific device. Thus, this loader is not very
|
||||
// good for multi-device.
|
||||
void VulkanLoadDeviceFunctions(VkDevice device) {
|
||||
void VulkanLoadDeviceFunctions(VkDevice device, const VulkanDeviceExtensions &enabledExtensions) {
|
||||
WLOG("Vulkan device functions loaded.");
|
||||
// TODO: Move more functions VulkanLoadInstanceFunctions to here.
|
||||
LOAD_DEVICE_FUNC(device, vkCreateSwapchainKHR);
|
||||
@ -590,9 +618,13 @@ void VulkanLoadDeviceFunctions(VkDevice device) {
|
||||
LOAD_DEVICE_FUNC(device, vkGetSwapchainImagesKHR);
|
||||
LOAD_DEVICE_FUNC(device, vkAcquireNextImageKHR);
|
||||
LOAD_DEVICE_FUNC(device, vkQueuePresentKHR);
|
||||
LOAD_DEVICE_FUNC(device, vkGetMemoryHostPointerPropertiesEXT);
|
||||
LOAD_DEVICE_FUNC(device, vkGetBufferMemoryRequirements2KHR);
|
||||
LOAD_DEVICE_FUNC(device, vkGetImageMemoryRequirements2KHR);
|
||||
if (enabledExtensions.EXT_external_memory_host) {
|
||||
LOAD_DEVICE_FUNC(device, vkGetMemoryHostPointerPropertiesEXT);
|
||||
}
|
||||
if (enabledExtensions.KHR_dedicated_allocation) {
|
||||
LOAD_DEVICE_FUNC(device, vkGetBufferMemoryRequirements2KHR);
|
||||
LOAD_DEVICE_FUNC(device, vkGetImageMemoryRequirements2KHR);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanFree() {
|
||||
|
@ -197,8 +197,16 @@ extern PFN_vkQueuePresentKHR vkQueuePresentKHR;
|
||||
|
||||
// And the DEBUG_REPORT extension. Since we load this dynamically even in static
|
||||
// linked mode, we have to rename it :(
|
||||
extern PFN_vkCreateDebugReportCallbackEXT dyn_vkCreateDebugReportCallbackEXT;
|
||||
extern PFN_vkDestroyDebugReportCallbackEXT dyn_vkDestroyDebugReportCallbackEXT;
|
||||
extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
|
||||
extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
|
||||
|
||||
extern PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
|
||||
extern PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT;
|
||||
extern PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT;
|
||||
extern PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT;
|
||||
extern PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT;
|
||||
extern PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT;
|
||||
extern PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT;
|
||||
|
||||
// Assorted other extensions.
|
||||
extern PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;
|
||||
@ -207,11 +215,30 @@ extern PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesE
|
||||
extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
|
||||
extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR;
|
||||
|
||||
|
||||
// For fast extension-enabled checks.
|
||||
struct VulkanDeviceExtensions {
|
||||
bool EXT_debug_report;
|
||||
bool EXT_debug_utils;
|
||||
bool KHR_maintenance1; // required for KHR_create_renderpass2
|
||||
bool KHR_maintenance2;
|
||||
bool KHR_maintenance3;
|
||||
bool KHR_multiview; // required for KHR_create_renderpass2
|
||||
bool KHR_get_memory_requirements2;
|
||||
bool KHR_dedicated_allocation;
|
||||
bool KHR_create_renderpass2;
|
||||
bool EXT_external_memory_host;
|
||||
bool KHR_get_physical_device_properties2;
|
||||
bool KHR_depth_stencil_resolve;
|
||||
bool EXT_shader_stencil_export;
|
||||
// bool EXT_depth_range_unrestricted; // Allows depth outside [0.0, 1.0] in 32-bit float depth buffers.
|
||||
};
|
||||
|
||||
// Way to do a quick check before even attempting to load.
|
||||
bool VulkanMayBeAvailable();
|
||||
void VulkanSetAvailable(bool available);
|
||||
|
||||
bool VulkanLoad();
|
||||
void VulkanLoadInstanceFunctions(VkInstance instance);
|
||||
void VulkanLoadDeviceFunctions(VkDevice device);
|
||||
void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensions &enabledExtensions);
|
||||
void VulkanLoadDeviceFunctions(VkDevice device, const VulkanDeviceExtensions &enabledExtensions);
|
||||
void VulkanFree();
|
||||
|
@ -124,8 +124,17 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
|
||||
return false;
|
||||
}
|
||||
if (g_validate_) {
|
||||
int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
||||
g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions);
|
||||
if (g_Vulkan->DeviceExtensions().EXT_debug_utils) {
|
||||
int bits = 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
|
||||
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
g_Vulkan->InitDebugUtilsCallback(&VulkanDebugUtilsCallback, bits, &g_LogOptions);
|
||||
} else {
|
||||
int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
||||
g_Vulkan->InitDebugMsgCallback(&VulkanDebugReportCallback, bits, &g_LogOptions);
|
||||
}
|
||||
}
|
||||
g_Vulkan->InitSurface(WINDOWSYSTEM_WIN32, (void *)hInst, (void *)hWnd);
|
||||
if (!g_Vulkan->InitObjects()) {
|
||||
@ -160,6 +169,7 @@ void WindowsVulkanContext::Shutdown() {
|
||||
g_Vulkan->WaitUntilQueueIdle();
|
||||
g_Vulkan->DestroyObjects();
|
||||
g_Vulkan->DestroyDevice();
|
||||
g_Vulkan->DestroyDebugUtilsCallback();
|
||||
g_Vulkan->DestroyDebugMsgCallback();
|
||||
g_Vulkan->DestroyInstance();
|
||||
|
||||
|
@ -160,6 +160,7 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB
|
||||
if (!success) {
|
||||
g_Vulkan->DestroyObjects();
|
||||
g_Vulkan->DestroyDevice();
|
||||
g_Vulkan->DestroyDebugUtilsCallback();
|
||||
g_Vulkan->DestroyDebugMsgCallback();
|
||||
|
||||
g_Vulkan->DestroyInstance();
|
||||
@ -181,6 +182,7 @@ void AndroidVulkanContext::ShutdownFromRenderThread() {
|
||||
void AndroidVulkanContext::Shutdown() {
|
||||
ILOG("Calling NativeShutdownGraphics");
|
||||
g_Vulkan->DestroyDevice();
|
||||
g_Vulkan->DestroyDebugUtilsCallback();
|
||||
g_Vulkan->DestroyDebugMsgCallback();
|
||||
|
||||
g_Vulkan->DestroyInstance();
|
||||
|
Loading…
x
Reference in New Issue
Block a user