@@ -14,82 +14,81 @@ We wrap the actual Physical Device and a few other useful objects into `struct G
1414constexpr auto vk_version_v = VK_MAKE_VERSION(1 , 3 , 0 );
1515
1616struct Gpu {
17- vk::PhysicalDevice device{};
18- vk::PhysicalDeviceProperties properties{};
19- vk::PhysicalDeviceFeatures features{};
20- std::uint32_t queue_family{};
17+ vk::PhysicalDevice device{};
18+ vk::PhysicalDeviceProperties properties{};
19+ vk::PhysicalDeviceFeatures features{};
20+ std::uint32_t queue_family{};
2121};
2222
2323[[nodiscard]] auto get_suitable_gpu (vk::Instance instance,
24- vk::SurfaceKHR surface) -> Gpu;
24+ vk::SurfaceKHR surface) -> Gpu;
2525```
2626
2727The implementation:
2828
2929```cpp
3030auto lvk::get_suitable_gpu(vk::Instance const instance,
31- vk::SurfaceKHR const surface) -> Gpu {
32- auto const supports_swapchain = [](Gpu const& gpu) {
33- static constexpr std::string_view name_v =
34- VK_KHR_SWAPCHAIN_EXTENSION_NAME;
35- static constexpr auto is_swapchain =
36- [](vk::ExtensionProperties const& properties) {
37- return properties.extensionName.data() == name_v;
38- };
39- auto const properties = gpu.device.enumerateDeviceExtensionProperties();
40- auto const it = std::ranges::find_if(properties, is_swapchain);
41- return it != properties.end();
42- };
43-
44- auto const set_queue_family = [](Gpu& out_gpu) {
45- static constexpr auto queue_flags_v =
46- vk::QueueFlagBits::eGraphics | vk::QueueFlagBits::eTransfer;
47- for (auto const [index, family] :
48- std::views::enumerate(out_gpu.device.getQueueFamilyProperties())) {
49- if ((family.queueFlags & queue_flags_v) == queue_flags_v) {
50- out_gpu.queue_family = static_cast<std::uint32_t>(index);
51- return true;
52- }
53- }
54- return false;
55- };
56-
57- auto const can_present = [surface](Gpu const& gpu) {
58- return gpu.device.getSurfaceSupportKHR(gpu.queue_family, surface) ==
59- vk::True;
60- };
61-
62- auto fallback = Gpu{};
63- for (auto const& device : instance.enumeratePhysicalDevices()) {
64- auto gpu = Gpu{.device = device, .properties = device.getProperties()};
65- if (gpu.properties.apiVersion < vk_version_v) { continue; }
66- if (!supports_swapchain(gpu)) { continue; }
67- if (!set_queue_family(gpu)) { continue; }
68- if (!can_present(gpu)) { continue; }
69- gpu.features = gpu.device.getFeatures();
70- if (gpu.properties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) {
71- return gpu;
72- }
73- // keep iterating in case we find a Discrete Gpu later.
74- fallback = gpu;
75- }
76- if (fallback.device) { return fallback; }
77-
78- throw std::runtime_error{"No suitable Vulkan Physical Devices"};
31+ vk::SurfaceKHR const surface) -> Gpu {
32+ auto const supports_swapchain = [](Gpu const& gpu) {
33+ static constexpr std::string_view name_v =
34+ VK_KHR_SWAPCHAIN_EXTENSION_NAME;
35+ static constexpr auto is_swapchain =
36+ [](vk::ExtensionProperties const& properties) {
37+ return properties.extensionName.data() == name_v;
38+ };
39+ auto const properties = gpu.device.enumerateDeviceExtensionProperties();
40+ auto const it = std::ranges::find_if(properties, is_swapchain);
41+ return it != properties.end();
42+ };
43+
44+ auto const set_queue_family = [](Gpu& out_gpu) {
45+ static constexpr auto queue_flags_v =
46+ vk::QueueFlagBits::eGraphics | vk::QueueFlagBits::eTransfer;
47+ for (auto const [index, family] :
48+ std::views::enumerate(out_gpu.device.getQueueFamilyProperties())) {
49+ if ((family.queueFlags & queue_flags_v) == queue_flags_v) {
50+ out_gpu.queue_family = static_cast<std::uint32_t>(index);
51+ return true;
52+ }
53+ }
54+ return false;
55+ };
56+
57+ auto const can_present = [surface](Gpu const& gpu) {
58+ return gpu.device.getSurfaceSupportKHR(gpu.queue_family, surface) ==
59+ vk::True;
60+ };
61+
62+ auto fallback = Gpu{};
63+ for (auto const& device : instance.enumeratePhysicalDevices()) {
64+ auto gpu = Gpu{.device = device, .properties = device.getProperties()};
65+ if (gpu.properties.apiVersion < vk_version_v) { continue; }
66+ if (!supports_swapchain(gpu)) { continue; }
67+ if (!set_queue_family(gpu)) { continue; }
68+ if (!can_present(gpu)) { continue; }
69+ gpu.features = gpu.device.getFeatures();
70+ if (gpu.properties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) {
71+ return gpu;
72+ }
73+ // keep iterating in case we find a Discrete Gpu later.
74+ fallback = gpu;
75+ }
76+ if (fallback.device) { return fallback; }
77+
78+ throw std::runtime_error{"No suitable Vulkan Physical Devices"};
7979}
8080```
8181
8282Finally, add a ` Gpu ` member in ` App ` and initialize it after ` create_surface() ` :
8383
8484``` cpp
85- create_surface ();
86- select_gpu ();
87- // ...
88-
85+ create_surface ();
86+ select_gpu ();
8987
88+ // ...
9089void App::select_gpu () {
91- m_gpu = get_suitable_gpu(*m_instance, *m_surface);
92- std::println ("Using GPU: {}",
93- std::string_view{m_gpu.properties.deviceName});
90+ m_gpu = get_suitable_gpu(* m_instance, * m_surface);
91+ std::println ("Using GPU: {}",
92+ std::string_view{m_gpu.properties.deviceName});
9493}
9594```
0 commit comments