Skip to content

Commit 9b47b09

Browse files
committed
Refactor PhysicalDevice selection
1 parent be52510 commit 9b47b09

File tree

4 files changed

+124
-180
lines changed

4 files changed

+124
-180
lines changed

app/plugins/gpu_selection/gpu_selection.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/* Copyright (c) 2023-2025, Sascha Willems
2-
* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
1+
/* Copyright (c) 2023-2026, Sascha Willems
2+
* Copyright (c) 2025-2026, NVIDIA CORPORATION. All rights reserved.
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*
@@ -18,6 +18,7 @@
1818

1919
#include "gpu_selection.h"
2020
#include "core/instance.h"
21+
#include "vulkan_sample.h"
2122

2223
#include <algorithm>
2324

@@ -45,8 +46,8 @@ bool GpuSelection::handle_option(std::deque<std::string> &arguments)
4546
}
4647
uint32_t gpu_index = static_cast<uint32_t>(std::stoul(arguments[1]));
4748

48-
vkb::core::InstanceC::selected_gpu_index = gpu_index;
49-
vkb::core::InstanceCpp::selected_gpu_index = gpu_index;
49+
vkb::VulkanSampleC::selected_gpu_index = gpu_index;
50+
vkb::VulkanSampleCpp::selected_gpu_index = gpu_index;
5051

5152
arguments.pop_front();
5253
arguments.pop_front();

framework/core/instance.h

Lines changed: 2 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,6 @@ class Instance
5959
using SurfaceType = typename std::conditional<bindingType == vkb::BindingType::Cpp, vk::SurfaceKHR, VkSurfaceKHR>::type;
6060

6161
public:
62-
/**
63-
* @brief Can be set from the GPU selection plugin to explicitly select a GPU instead
64-
*/
65-
inline static uint32_t selected_gpu_index = ~0;
66-
6762
/**
6863
* @brief Initializes the connection to Vulkan
6964
* @param application_name The name of the application
@@ -112,38 +107,17 @@ class Instance
112107

113108
const std::vector<std::string> &get_extensions();
114109

115-
/**
116-
* @brief Tries to find the first available discrete GPU
117-
* @returns A valid physical device
118-
*/
119-
PhysicalDevice<bindingType> &get_first_gpu();
120-
121110
InstanceType get_handle() const;
122111

123-
/**
124-
* @brief Tries to find the first available discrete GPU that can render to the given surface
125-
* @param surface to test against
126-
* @param headless_surface Is surface created with VK_EXT_headless_surface
127-
* @returns A valid physical device
128-
*/
129-
PhysicalDevice<bindingType> &get_suitable_gpu(SurfaceType surface, bool headless_surface);
130-
131112
/**
132113
* @brief Checks if the given extension is enabled in the InstanceType
133114
* @param extension An extension to check
134115
*/
135116
bool is_enabled(char const *extension) const;
136117

137118
private:
138-
/**
139-
* @brief Queries the instance for the physical devices on the machine
140-
*/
141-
void query_gpus();
142-
143-
private:
144-
std::vector<std::string> enabled_extensions; // The enabled extensions
145-
std::vector<std::unique_ptr<vkb::core::PhysicalDeviceCpp>> gpus; // The physical devices found on the machine
146-
vk::Instance handle; // The Vulkan instance
119+
std::vector<std::string> enabled_extensions; // The enabled extensions
120+
vk::Instance handle; // The Vulkan instance
147121

148122
#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS)
149123
vk::DebugReportCallbackEXT debug_report_callback; // The debug report callback
@@ -349,8 +323,6 @@ inline Instance<bindingType>::Instance(std::string const
349323
debug_report_callback = handle.createDebugReportCallbackEXT(vkb::core::getDefaultDebugReportCallbackCreateInfoEXT());
350324
}
351325
#endif
352-
353-
query_gpus();
354326
}
355327

356328
template <vkb::BindingType bindingType>
@@ -375,15 +347,6 @@ inline Instance<bindingType>::Instance(vk::Instance instance, const std::vector<
375347
{
376348
enabled_extensions.push_back(extension);
377349
}
378-
379-
if (handle)
380-
{
381-
query_gpus();
382-
}
383-
else
384-
{
385-
throw std::runtime_error("Instance not valid");
386-
}
387350
}
388351

389352
template <vkb::BindingType bindingType>
@@ -419,28 +382,6 @@ inline Instance<bindingType>::~Instance()
419382
# undef USE_VALIDATION_LAYER_FEATURES
420383
#endif
421384

422-
template <vkb::BindingType bindingType>
423-
inline PhysicalDevice<bindingType> &Instance<bindingType>::get_first_gpu()
424-
{
425-
assert(!gpus.empty() && "No physical devices were found on the system.");
426-
427-
// Find a discrete GPU
428-
auto gpuIt = std::ranges::find_if(gpus, [](auto const &gpu) { return gpu->get_properties().deviceType == vk::PhysicalDeviceType::eDiscreteGpu; });
429-
if (gpuIt == gpus.end())
430-
{
431-
LOGW("Couldn't find a discrete physical device, picking default GPU");
432-
gpuIt = gpus.begin();
433-
}
434-
if constexpr (bindingType == BindingType::Cpp)
435-
{
436-
return **gpuIt;
437-
}
438-
else
439-
{
440-
return reinterpret_cast<vkb::core::PhysicalDeviceC &>(**gpuIt);
441-
}
442-
}
443-
444385
template <vkb::BindingType bindingType>
445386
inline typename Instance<bindingType>::InstanceType Instance<bindingType>::get_handle() const
446387
{
@@ -455,103 +396,13 @@ inline typename Instance<bindingType>::InstanceType Instance<bindingType>::get_h
455396
return handle;
456397
}
457398

458-
template <vkb::BindingType bindingType>
459-
inline PhysicalDevice<bindingType> &Instance<bindingType>::get_suitable_gpu(SurfaceType surface, bool headless_surface)
460-
{
461-
assert(!gpus.empty() && "No physical devices were found on the system.");
462-
463-
// A GPU can be explicitly selected via the command line (see plugins/gpu_selection.cpp), this overrides the below GPU selection algorithm
464-
auto gpuIt = gpus.begin();
465-
if (selected_gpu_index != ~0)
466-
{
467-
LOGI("Explicitly selecting GPU {}", selected_gpu_index);
468-
if (selected_gpu_index > gpus.size() - 1)
469-
{
470-
throw std::runtime_error("Selected GPU index is not within no. of available GPUs");
471-
}
472-
gpuIt = gpus.begin() + selected_gpu_index;
473-
}
474-
else
475-
{
476-
if (headless_surface)
477-
{
478-
LOGW("Using headless surface with multiple GPUs. Considered explicitly selecting the target GPU.")
479-
}
480-
481-
// Find a discrete GPU
482-
#if 0
483-
gpuIt = std::ranges::find_if(gpus,
484-
[&surface](auto const &gpu) {
485-
return (gpu->get_properties().deviceType == vk::PhysicalDeviceType::eDiscreteGpu) &&
486-
std::ranges::any_of(std::views::iota(size_t(0), gpu->get_queue_family_properties().size()),
487-
[&gpu, &surface](auto const &queue_idx) {
488-
return gpu->get_handle().getSurfaceSupportKHR(static_cast<uint32_t>(queue_idx), surface);
489-
});
490-
});
491-
#else
492-
gpuIt = std::ranges::find_if(gpus,
493-
[&surface](auto const &gpu) {
494-
auto gpu_supports_surface = [&gpu, &surface]() {
495-
for (uint32_t queue_idx = 0; queue_idx < gpu->get_queue_family_properties().size(); ++queue_idx)
496-
{
497-
if (gpu->get_handle().getSurfaceSupportKHR(queue_idx, surface))
498-
{
499-
return true;
500-
}
501-
}
502-
return false;
503-
};
504-
return (gpu->get_properties().deviceType == vk::PhysicalDeviceType::eDiscreteGpu) && gpu_supports_surface();
505-
});
506-
#endif
507-
if (gpuIt == gpus.end())
508-
{
509-
LOGW("Couldn't find a discrete physical device that supports the surface, picking default GPU");
510-
gpuIt = gpus.begin();
511-
}
512-
}
513-
514-
if constexpr (bindingType == BindingType::Cpp)
515-
{
516-
return **gpuIt;
517-
}
518-
else
519-
{
520-
return reinterpret_cast<vkb::core::PhysicalDeviceC &>(**gpuIt);
521-
}
522-
}
523-
524399
template <vkb::BindingType bindingType>
525400
inline bool Instance<bindingType>::is_enabled(char const *extension) const
526401
{
527402
return std::ranges::find_if(enabled_extensions, [extension](std::string const &enabled_extension) { return enabled_extension == extension; }) !=
528403
enabled_extensions.end();
529404
}
530405

531-
template <vkb::BindingType bindingType>
532-
inline void Instance<bindingType>::query_gpus()
533-
{
534-
// Querying valid physical devices on the machine
535-
std::vector<vk::PhysicalDevice> physical_devices = handle.enumeratePhysicalDevices();
536-
if (physical_devices.empty())
537-
{
538-
throw std::runtime_error("Couldn't find a physical device that supports Vulkan.");
539-
}
540-
541-
// Create gpus wrapper objects from the vk::PhysicalDevice's
542-
for (auto &physical_device : physical_devices)
543-
{
544-
if constexpr (bindingType == BindingType::Cpp)
545-
{
546-
gpus.push_back(std::make_unique<vkb::core::PhysicalDeviceCpp>(*this, physical_device));
547-
}
548-
else
549-
{
550-
gpus.push_back(std::make_unique<vkb::core::PhysicalDeviceCpp>(*reinterpret_cast<vkb::core::InstanceCpp *>(this), physical_device));
551-
}
552-
}
553-
}
554-
555406
template <vkb::BindingType bindingType>
556407
inline std::vector<std::string> const &Instance<bindingType>::get_extensions()
557408
{

framework/platform/unix/direct_window.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2019-2025, Arm Limited and Contributors
1+
/* Copyright (c) 2019-2026, Arm Limited and Contributors
22
*
33
* SPDX-License-Identifier: Apache-2.0
44
*
@@ -242,22 +242,6 @@ DirectWindow::~DirectWindow()
242242
}
243243
}
244244

245-
VkSurfaceKHR DirectWindow::create_surface(vkb::core::InstanceC &instance)
246-
{
247-
return create_surface(instance.get_handle(), instance.get_first_gpu().get_handle());
248-
}
249-
250-
// Local structure for holding display candidate information
251-
struct Candidate
252-
{
253-
VkDisplayKHR display;
254-
VkDisplayPropertiesKHR display_props;
255-
VkDisplayModePropertiesKHR mode;
256-
VkDisplayPlaneCapabilitiesKHR caps;
257-
uint32_t plane_index;
258-
uint32_t stack_index;
259-
};
260-
261245
// Helper template to get a vector of properties using the Vulkan idiom of
262246
// querying size, then querying data
263247
template <typename T, typename F, typename... Targs>
@@ -275,6 +259,22 @@ static std::vector<T> get_props(F func, Targs... args)
275259
return result;
276260
}
277261

262+
VkSurfaceKHR DirectWindow::create_surface(vkb::core::InstanceC &instance)
263+
{
264+
return create_surface(instance.get_handle(), get_props<VkPhysicalDevice>(vkEnumeratePhysicalDevices, instance.get_handle()).front());
265+
}
266+
267+
// Local structure for holding display candidate information
268+
struct Candidate
269+
{
270+
VkDisplayKHR display;
271+
VkDisplayPropertiesKHR display_props;
272+
VkDisplayModePropertiesKHR mode;
273+
VkDisplayPlaneCapabilitiesKHR caps;
274+
uint32_t plane_index;
275+
uint32_t stack_index;
276+
};
277+
278278
// Find all valid display candidates in the system
279279
static std::vector<Candidate> find_display_candidates(VkPhysicalDevice phys_dev, Window::Mode window_mode)
280280
{

0 commit comments

Comments
 (0)