|
@@ -56,7 +56,15 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags,
|
|
|
}
|
|
|
#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;
|
|
|
|
|
@@ -64,31 +72,44 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
|
|
|
{
|
|
|
VkInstanceCreateInfo create_info = {};
|
|
|
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
|
|
- create_info.enabledExtensionCount = extensions_count;
|
|
|
- create_info.ppEnabledExtensionNames = extensions;
|
|
|
-#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
|
|
+
|
|
|
+ // Enumerate available extensions
|
|
|
+ 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
|
|
|
+#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
|
|
const char* layers[] = { "VK_LAYER_KHRONOS_validation" };
|
|
|
create_info.enabledLayerCount = 1;
|
|
|
create_info.ppEnabledLayerNames = layers;
|
|
|
-
|
|
|
- // Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it)
|
|
|
- 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;
|
|
|
+ extensions.push_back("VK_EXT_debug_report");
|
|
|
+#endif
|
|
|
|
|
|
// Create Vulkan Instance
|
|
|
+ create_info.enabledExtensionCount = (uint32_t)extensions.size();
|
|
|
+ create_info.ppEnabledExtensionNames = extensions.Data;
|
|
|
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
|
|
|
check_vk_result(err);
|
|
|
- free(extensions_ext);
|
|
|
|
|
|
- // Get the function pointer (required for any extensions)
|
|
|
+ // Setup the debug report callback
|
|
|
+#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
|
|
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
|
|
|
IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
|
|
|
-
|
|
|
- // Setup the debug report callback
|
|
|
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
|
|
|
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;
|
|
@@ -96,11 +117,6 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
|
|
|
debug_report_ci.pUserData = nullptr;
|
|
|
err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
|
|
|
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
|
|
|
}
|
|
|
|
|
@@ -358,12 +374,13 @@ int main(int, char**)
|
|
|
// Create window with Vulkan graphics context
|
|
|
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);
|
|
|
+
|
|
|
+ ImVector<const char*> extensions;
|
|
|
uint32_t extensions_count = 0;
|
|
|
SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, nullptr);
|
|
|
- const char** extensions = new const char*[extensions_count];
|
|
|
- SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, extensions);
|
|
|
- SetupVulkan(extensions, extensions_count);
|
|
|
- delete[] extensions;
|
|
|
+ extensions.resize(extensions_count);
|
|
|
+ SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, extensions.Data);
|
|
|
+ SetupVulkan(extensions);
|
|
|
|
|
|
// Create Window Surface
|
|
|
VkSurfaceKHR surface;
|