Skip to content

Commit

Permalink
Examples: Vulkan: further work for device extensions + tentative use …
Browse files Browse the repository at this point in the history
…o fVK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME. (#6109, #6172, #6101)
  • Loading branch information
ocornut committed Apr 13, 2023
1 parent 6324280 commit ba98667
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 78 deletions.
89 changes: 50 additions & 39 deletions examples/example_glfw_vulkan/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;

Expand All @@ -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
Expand All @@ -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);

Expand All @@ -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
{
Expand All @@ -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;
Expand All @@ -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);
Expand Down
89 changes: 50 additions & 39 deletions examples/example_sdl2_vulkan/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -64,7 +65,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;

Expand All @@ -83,11 +109,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
Expand All @@ -97,12 +123,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);

Expand All @@ -120,35 +146,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
{
Expand All @@ -168,8 +167,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;
Expand All @@ -180,8 +191,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);
Expand Down

0 comments on commit ba98667

Please sign in to comment.