Examples: Vulkan: rework extensions setup + enable some to avoid validation layer errors. (#6109, #6172, #6101)

Enable VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
This commit is contained in:
ocornut 2023-04-13 13:39:28 +02:00
parent 995f92a456
commit 6324280432
3 changed files with 88 additions and 48 deletions

View File

@ -94,6 +94,9 @@ Other changes:
(#6314) [@PathogenDavid] (#6314) [@PathogenDavid]
- Backends: WebGPU: Align buffers. Use WGSL shaders instead of SPIR-V. Add gamma uniform. (#6188) [@eliemichel] - Backends: WebGPU: Align buffers. Use WGSL shaders instead of SPIR-V. Add gamma uniform. (#6188) [@eliemichel]
- Backends: WebGPU: Reorganized to store data in io.BackendRendererUserData like other backends. - Backends: WebGPU: Reorganized to store data in io.BackendRendererUserData like other backends.
- Examples: Vulkan: Fixed validation errors with newer VulkanSDK by explicitely querying and enabling
"VK_KHR_get_physical_device_properties2", "VK_KHR_portability_enumeration", and
VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR. (#6109, #6172, #6101)
- Examples: Windows: Added 'misc/debuggers/imgui.natstepfilter' file to all Visual Studio projects, - Examples: Windows: Added 'misc/debuggers/imgui.natstepfilter' file to all Visual Studio projects,
now that VS 2022 17.6 Preview 2 support adding Debug Step Filter spec files into projects. now that VS 2022 17.6 Preview 2 support adding Debug Step Filter spec files into projects.
- Examples: SDL3: Updated for latest WIP SDL3 branch. (#6243) - Examples: SDL3: Updated for latest WIP SDL3 branch. (#6243)

View File

@ -68,7 +68,15 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags,
} }
#endif // IMGUI_VULKAN_DEBUG_REPORT #endif // IMGUI_VULKAN_DEBUG_REPORT
static void SetupVulkan(const char** extensions, uint32_t extensions_count) static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properties, const char* extension)
{
for (const VkExtensionProperties& p : properties)
if (strcmp(p.extensionName, extension) == 0)
return true;
return false;
}
static void SetupVulkan(ImVector<const char*> extensions)
{ {
VkResult err; VkResult err;
@ -76,31 +84,44 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
{ {
VkInstanceCreateInfo create_info = {}; VkInstanceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
create_info.enabledExtensionCount = extensions_count;
create_info.ppEnabledExtensionNames = extensions; // Enumerate available extensions
#ifdef IMGUI_VULKAN_DEBUG_REPORT uint32_t properties_count;
ImVector<VkExtensionProperties> properties;
vkEnumerateInstanceExtensionProperties(nullptr, &properties_count, nullptr);
properties.resize(properties_count);
err = vkEnumerateInstanceExtensionProperties(nullptr, &properties_count, properties.Data);
check_vk_result(err);
// Enable required extensions
if (IsExtensionAvailable(properties, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
#ifdef VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME
if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME))
{
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
#endif
// Enabling validation layers // Enabling validation layers
#ifdef IMGUI_VULKAN_DEBUG_REPORT
const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; const char* layers[] = { "VK_LAYER_KHRONOS_validation" };
create_info.enabledLayerCount = 1; create_info.enabledLayerCount = 1;
create_info.ppEnabledLayerNames = layers; create_info.ppEnabledLayerNames = layers;
extensions.push_back("VK_EXT_debug_report");
// Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it) #endif
const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1));
memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*));
extensions_ext[extensions_count] = "VK_EXT_debug_report";
create_info.enabledExtensionCount = extensions_count + 1;
create_info.ppEnabledExtensionNames = extensions_ext;
// Create Vulkan Instance // Create Vulkan Instance
create_info.enabledExtensionCount = (uint32_t)extensions.size();
create_info.ppEnabledExtensionNames = extensions.Data;
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err); check_vk_result(err);
free(extensions_ext);
// Get the function pointer (required for any extensions)
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
// Setup the debug report callback // Setup the debug report callback
#ifdef IMGUI_VULKAN_DEBUG_REPORT
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
@ -108,11 +129,6 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
debug_report_ci.pUserData = nullptr; debug_report_ci.pUserData = nullptr;
err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
check_vk_result(err); check_vk_result(err);
#else
// Create Vulkan Instance without any debug feature
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err);
IM_UNUSED(g_DebugReport);
#endif #endif
} }
@ -367,9 +383,13 @@ int main(int, char**)
printf("GLFW: Vulkan Not Supported\n"); printf("GLFW: Vulkan Not Supported\n");
return 1; return 1;
} }
ImVector<const char*> extensions;
uint32_t extensions_count = 0; uint32_t extensions_count = 0;
const char** extensions = glfwGetRequiredInstanceExtensions(&extensions_count); const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&extensions_count);
SetupVulkan(extensions, extensions_count); for (uint32_t i = 0; i < extensions_count; i++)
extensions.push_back(glfw_extensions[i]);
SetupVulkan(extensions);
// Create Window Surface // Create Window Surface
VkSurfaceKHR surface; VkSurfaceKHR surface;

View File

@ -56,7 +56,15 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags,
} }
#endif // IMGUI_VULKAN_DEBUG_REPORT #endif // IMGUI_VULKAN_DEBUG_REPORT
static void SetupVulkan(const char** extensions, uint32_t extensions_count) static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properties, const char* extension)
{
for (const VkExtensionProperties& p : properties)
if (strcmp(p.extensionName, extension) == 0)
return true;
return false;
}
static void SetupVulkan(ImVector<const char*> extensions)
{ {
VkResult err; VkResult err;
@ -64,31 +72,44 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
{ {
VkInstanceCreateInfo create_info = {}; VkInstanceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
create_info.enabledExtensionCount = extensions_count;
create_info.ppEnabledExtensionNames = extensions; // Enumerate available extensions
#ifdef IMGUI_VULKAN_DEBUG_REPORT uint32_t properties_count;
ImVector<VkExtensionProperties> properties;
vkEnumerateInstanceExtensionProperties(nullptr, &properties_count, nullptr);
properties.resize(properties_count);
err = vkEnumerateInstanceExtensionProperties(nullptr, &properties_count, properties.Data);
check_vk_result(err);
// Enable required extensions
if (IsExtensionAvailable(properties, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
#ifdef VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME
if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME))
{
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
#endif
// Enabling validation layers // Enabling validation layers
#ifdef IMGUI_VULKAN_DEBUG_REPORT
const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; const char* layers[] = { "VK_LAYER_KHRONOS_validation" };
create_info.enabledLayerCount = 1; create_info.enabledLayerCount = 1;
create_info.ppEnabledLayerNames = layers; create_info.ppEnabledLayerNames = layers;
extensions.push_back("VK_EXT_debug_report");
// Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it) #endif
const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1));
memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*));
extensions_ext[extensions_count] = "VK_EXT_debug_report";
create_info.enabledExtensionCount = extensions_count + 1;
create_info.ppEnabledExtensionNames = extensions_ext;
// Create Vulkan Instance // Create Vulkan Instance
create_info.enabledExtensionCount = (uint32_t)extensions.size();
create_info.ppEnabledExtensionNames = extensions.Data;
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err); check_vk_result(err);
free(extensions_ext);
// Get the function pointer (required for any extensions)
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
// Setup the debug report callback // Setup the debug report callback
#ifdef IMGUI_VULKAN_DEBUG_REPORT
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
@ -96,11 +117,6 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
debug_report_ci.pUserData = nullptr; debug_report_ci.pUserData = nullptr;
err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
check_vk_result(err); check_vk_result(err);
#else
// Create Vulkan Instance without any debug feature
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err);
IM_UNUSED(g_DebugReport);
#endif #endif
} }
@ -358,12 +374,13 @@ int main(int, char**)
// Create window with Vulkan graphics context // Create window with Vulkan graphics context
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
ImVector<const char*> extensions;
uint32_t extensions_count = 0; uint32_t extensions_count = 0;
SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, nullptr); SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, nullptr);
const char** extensions = new const char*[extensions_count]; extensions.resize(extensions_count);
SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, extensions); SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, extensions.Data);
SetupVulkan(extensions, extensions_count); SetupVulkan(extensions);
delete[] extensions;
// Create Window Surface // Create Window Surface
VkSurfaceKHR surface; VkSurfaceKHR surface;