Examples: Vulkan: further work for device extensions + tentative use o fVK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME. (#6109, #6172, #6101)
diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp
index d321391..43ac22f 100644
--- a/examples/example_glfw_vulkan/main.cpp
+++ b/examples/example_glfw_vulkan/main.cpp
@@ -18,6 +18,7 @@
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#include <vulkan/vulkan.h>
+//#include <vulkan/vulkan_beta.h>
// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers.
// To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma.
@@ -76,7 +77,32 @@
return false;
}
-static void SetupVulkan(ImVector<const char*> extensions)
+static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice()
+{
+ uint32_t gpu_count;
+ VkResult err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr);
+ check_vk_result(err);
+ IM_ASSERT(gpu_count > 0);
+
+ ImVector<VkPhysicalDevice> gpus;
+ gpus.resize(gpu_count);
+ err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus.Data);
+ check_vk_result(err);
+
+ // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers
+ // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple
+ // dedicated GPUs) is out of scope of this sample.
+ for (VkPhysicalDevice& device : gpus)
+ {
+ VkPhysicalDeviceProperties properties;
+ vkGetPhysicalDeviceProperties(device, &properties);
+ if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
+ return device;
+ }
+ return VK_NULL_HANDLE;
+}
+
+static void SetupVulkan(ImVector<const char*> instance_extensions)
{
VkResult err;
@@ -95,11 +121,11 @@
// 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);
+ instance_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);
+ instance_extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
#endif
@@ -109,12 +135,12 @@
const char* layers[] = { "VK_LAYER_KHRONOS_validation" };
create_info.enabledLayerCount = 1;
create_info.ppEnabledLayerNames = layers;
- extensions.push_back("VK_EXT_debug_report");
+ instance_extensions.push_back("VK_EXT_debug_report");
#endif
// Create Vulkan Instance
- create_info.enabledExtensionCount = (uint32_t)extensions.size();
- create_info.ppEnabledExtensionNames = extensions.Data;
+ create_info.enabledExtensionCount = (uint32_t)instance_extensions.Size;
+ create_info.ppEnabledExtensionNames = instance_extensions.Data;
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err);
@@ -132,35 +158,8 @@
#endif
}
- // Select GPU
- {
- uint32_t gpu_count;
- err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr);
- check_vk_result(err);
- IM_ASSERT(gpu_count > 0);
-
- VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count);
- err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus);
- check_vk_result(err);
-
- // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers
- // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple
- // dedicated GPUs) is out of scope of this sample.
- int use_gpu = 0;
- for (int i = 0; i < (int)gpu_count; i++)
- {
- VkPhysicalDeviceProperties properties;
- vkGetPhysicalDeviceProperties(gpus[i], &properties);
- if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
- {
- use_gpu = i;
- break;
- }
- }
-
- g_PhysicalDevice = gpus[use_gpu];
- free(gpus);
- }
+ // Select Physical Device (GPU)
+ g_PhysicalDevice = SetupVulkan_SelectPhysicalDevice();
// Select graphics queue family
{
@@ -180,8 +179,20 @@
// Create Logical Device (with 1 queue)
{
- int device_extension_count = 1;
- const char* device_extensions[] = { "VK_KHR_swapchain" };
+ ImVector<const char*> device_extensions;
+ device_extensions.push_back("VK_KHR_swapchain");
+
+ // Enumerate physical device extension
+ uint32_t properties_count;
+ ImVector<VkExtensionProperties> properties;
+ vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, nullptr);
+ properties.resize(properties_count);
+ vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, properties.Data);
+#ifdef VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME
+ if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME))
+ device_extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
+#endif
+
const float queue_priority[] = { 1.0f };
VkDeviceQueueCreateInfo queue_info[1] = {};
queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@@ -192,8 +203,8 @@
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]);
create_info.pQueueCreateInfos = queue_info;
- create_info.enabledExtensionCount = device_extension_count;
- create_info.ppEnabledExtensionNames = device_extensions;
+ create_info.enabledExtensionCount = (uint32_t)device_extensions.Size;
+ create_info.ppEnabledExtensionNames = device_extensions.Data;
err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device);
check_vk_result(err);
vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue);
diff --git a/examples/example_sdl2_vulkan/main.cpp b/examples/example_sdl2_vulkan/main.cpp
index 7c782eb..db78acd 100644
--- a/examples/example_sdl2_vulkan/main.cpp
+++ b/examples/example_sdl2_vulkan/main.cpp
@@ -17,6 +17,7 @@
#include <SDL.h>
#include <SDL_vulkan.h>
#include <vulkan/vulkan.h>
+//#include <vulkan/vulkan_beta.h>
//#define IMGUI_UNLIMITED_FRAME_RATE
#ifdef _DEBUG
@@ -64,7 +65,32 @@
return false;
}
-static void SetupVulkan(ImVector<const char*> extensions)
+static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice()
+{
+ uint32_t gpu_count;
+ VkResult err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr);
+ check_vk_result(err);
+ IM_ASSERT(gpu_count > 0);
+
+ ImVector<VkPhysicalDevice> gpus;
+ gpus.resize(gpu_count);
+ err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus.Data);
+ check_vk_result(err);
+
+ // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers
+ // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple
+ // dedicated GPUs) is out of scope of this sample.
+ for (VkPhysicalDevice& device : gpus)
+ {
+ VkPhysicalDeviceProperties properties;
+ vkGetPhysicalDeviceProperties(device, &properties);
+ if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
+ return device;
+ }
+ return VK_NULL_HANDLE;
+}
+
+static void SetupVulkan(ImVector<const char*> instance_extensions)
{
VkResult err;
@@ -83,11 +109,11 @@
// 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);
+ instance_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);
+ instance_extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
#endif
@@ -97,12 +123,12 @@
const char* layers[] = { "VK_LAYER_KHRONOS_validation" };
create_info.enabledLayerCount = 1;
create_info.ppEnabledLayerNames = layers;
- extensions.push_back("VK_EXT_debug_report");
+ instance_extensions.push_back("VK_EXT_debug_report");
#endif
// Create Vulkan Instance
- create_info.enabledExtensionCount = (uint32_t)extensions.size();
- create_info.ppEnabledExtensionNames = extensions.Data;
+ create_info.enabledExtensionCount = (uint32_t)instance_extensions.Size;
+ create_info.ppEnabledExtensionNames = instance_extensions.Data;
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err);
@@ -120,35 +146,8 @@
#endif
}
- // Select GPU
- {
- uint32_t gpu_count;
- err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr);
- check_vk_result(err);
- IM_ASSERT(gpu_count > 0);
-
- VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count);
- err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus);
- check_vk_result(err);
-
- // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers
- // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple
- // dedicated GPUs) is out of scope of this sample.
- int use_gpu = 0;
- for (int i = 0; i < (int)gpu_count; i++)
- {
- VkPhysicalDeviceProperties properties;
- vkGetPhysicalDeviceProperties(gpus[i], &properties);
- if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
- {
- use_gpu = i;
- break;
- }
- }
-
- g_PhysicalDevice = gpus[use_gpu];
- free(gpus);
- }
+ // Select Physical Device (GPU)
+ g_PhysicalDevice = SetupVulkan_SelectPhysicalDevice();
// Select graphics queue family
{
@@ -168,8 +167,20 @@
// Create Logical Device (with 1 queue)
{
- int device_extension_count = 1;
- const char* device_extensions[] = { "VK_KHR_swapchain" };
+ ImVector<const char*> device_extensions;
+ device_extensions.push_back("VK_KHR_swapchain");
+
+ // Enumerate physical device extension
+ uint32_t properties_count;
+ ImVector<VkExtensionProperties> properties;
+ vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, nullptr);
+ properties.resize(properties_count);
+ vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, properties.Data);
+#ifdef VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME
+ if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME))
+ device_extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
+#endif
+
const float queue_priority[] = { 1.0f };
VkDeviceQueueCreateInfo queue_info[1] = {};
queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@@ -180,8 +191,8 @@
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]);
create_info.pQueueCreateInfos = queue_info;
- create_info.enabledExtensionCount = device_extension_count;
- create_info.ppEnabledExtensionNames = device_extensions;
+ create_info.enabledExtensionCount = (uint32_t)device_extensions.Size;
+ create_info.ppEnabledExtensionNames = device_extensions.Data;
err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device);
check_vk_result(err);
vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue);