|
@@ -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 @@ static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properti
|
|
|
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 @@ static void SetupVulkan(ImVector<const char*> extensions)
|
|
|
|
|
|
// 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 @@ static void SetupVulkan(ImVector<const char*> extensions)
|
|
|
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 @@ static void SetupVulkan(ImVector<const char*> extensions)
|
|
|
#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 @@ static void SetupVulkan(ImVector<const char*> extensions)
|
|
|
|
|
|
// 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 @@ static void SetupVulkan(ImVector<const char*> extensions)
|
|
|
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);
|