|
29 | 29 | #include <sstream>
|
30 | 30 | #include <iostream>
|
31 | 31 | #include <memory>
|
| 32 | +#include <map> |
32 | 33 |
|
33 | 34 | #if defined(VK_USE_PLATFORM_XLIB_KHR)
|
34 | 35 | #include "xlib_loader.h"
|
@@ -317,6 +318,7 @@ struct Demo {
|
317 | 318 | void init(int argc, char **argv);
|
318 | 319 | void check_and_set_wsi_platform();
|
319 | 320 | void init_vk();
|
| 321 | + void select_physical_device(); |
320 | 322 | void init_vk_swapchain();
|
321 | 323 | void prepare();
|
322 | 324 | void prepare_buffers();
|
@@ -1700,7 +1702,9 @@ void Demo::init_vk() {
|
1700 | 1702 | VERIFY(create_debug_messenger_return.result == vk::Result::eSuccess);
|
1701 | 1703 | debug_messenger = create_debug_messenger_return.value;
|
1702 | 1704 | }
|
| 1705 | +} |
1703 | 1706 |
|
| 1707 | +void Demo::select_physical_device() { |
1704 | 1708 | auto physical_device_return = inst.enumeratePhysicalDevices();
|
1705 | 1709 | VERIFY(physical_device_return.result == vk::Result::eSuccess);
|
1706 | 1710 | auto physical_devices = physical_device_return.value;
|
@@ -1734,32 +1738,33 @@ void Demo::init_vk() {
|
1734 | 1738 | } else {
|
1735 | 1739 | /* Try to auto select most suitable device */
|
1736 | 1740 | if (gpu_number == -1) {
|
1737 |
| - constexpr uint32_t device_type_count = static_cast<uint32_t>(vk::PhysicalDeviceType::eCpu) + 1; |
1738 |
| - std::array<uint32_t, device_type_count> count_device_type{}; |
1739 |
| - |
| 1741 | + int prev_priority = 0; |
1740 | 1742 | for (uint32_t i = 0; i < physical_devices.size(); i++) {
|
1741 | 1743 | const auto physicalDeviceProperties = physical_devices[i].getProperties();
|
1742 | 1744 | assert(physicalDeviceProperties.deviceType <= vk::PhysicalDeviceType::eCpu);
|
1743 |
| - count_device_type[static_cast<int>(physicalDeviceProperties.deviceType)]++; |
1744 |
| - } |
1745 | 1745 |
|
1746 |
| - std::array<vk::PhysicalDeviceType, device_type_count> const device_type_preference = { |
1747 |
| - vk::PhysicalDeviceType::eDiscreteGpu, vk::PhysicalDeviceType::eIntegratedGpu, vk::PhysicalDeviceType::eVirtualGpu, |
1748 |
| - vk::PhysicalDeviceType::eCpu, vk::PhysicalDeviceType::eOther}; |
| 1746 | + auto support_result = physical_devices[i].getSurfaceSupportKHR(0, surface); |
| 1747 | + if (support_result.result != vk::Result::eSuccess || |
| 1748 | + support_result.value != vk::True) { |
| 1749 | + continue; |
| 1750 | + } |
1749 | 1751 |
|
1750 |
| - vk::PhysicalDeviceType search_for_device_type = vk::PhysicalDeviceType::eDiscreteGpu; |
1751 |
| - for (uint32_t i = 0; i < sizeof(device_type_preference) / sizeof(vk::PhysicalDeviceType); i++) { |
1752 |
| - if (count_device_type[static_cast<int>(device_type_preference[i])]) { |
1753 |
| - search_for_device_type = device_type_preference[i]; |
1754 |
| - break; |
| 1752 | + std::map<vk::PhysicalDeviceType, int> device_type_priorities = { |
| 1753 | + {vk::PhysicalDeviceType::eDiscreteGpu, 5}, |
| 1754 | + {vk::PhysicalDeviceType::eIntegratedGpu, 4}, |
| 1755 | + {vk::PhysicalDeviceType::eVirtualGpu, 3}, |
| 1756 | + {vk::PhysicalDeviceType::eCpu, 2}, |
| 1757 | + {vk::PhysicalDeviceType::eOther, 1}, |
| 1758 | + }; |
| 1759 | + int priority = -1; |
| 1760 | + if (device_type_priorities.find(physicalDeviceProperties.deviceType) != |
| 1761 | + device_type_priorities.end()) { |
| 1762 | + priority = device_type_priorities[physicalDeviceProperties.deviceType]; |
1755 | 1763 | }
|
1756 |
| - } |
1757 | 1764 |
|
1758 |
| - for (uint32_t i = 0; i < physical_devices.size(); i++) { |
1759 |
| - const auto physicalDeviceProperties = physical_devices[i].getProperties(); |
1760 |
| - if (physicalDeviceProperties.deviceType == search_for_device_type) { |
| 1765 | + if (priority > prev_priority) { |
1761 | 1766 | gpu_number = i;
|
1762 |
| - break; |
| 1767 | + prev_priority = priority; |
1763 | 1768 | }
|
1764 | 1769 | }
|
1765 | 1770 | }
|
@@ -1877,7 +1882,6 @@ void Demo::create_surface() {
|
1877 | 1882 | }
|
1878 | 1883 |
|
1879 | 1884 | void Demo::init_vk_swapchain() {
|
1880 |
| - create_surface(); |
1881 | 1885 | // Iterate over each queue to learn whether it supports presenting:
|
1882 | 1886 | std::vector<vk::Bool32> supportsPresent;
|
1883 | 1887 | for (uint32_t i = 0; i < static_cast<uint32_t>(queue_props.size()); i++) {
|
@@ -3744,6 +3748,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine,
|
3744 | 3748 | demo.connection = hInstance;
|
3745 | 3749 | demo.name = "Vulkan Cube";
|
3746 | 3750 | demo.create_window();
|
| 3751 | + demo.create_surface(); |
| 3752 | + demo.select_physical_device(); |
3747 | 3753 | demo.init_vk_swapchain();
|
3748 | 3754 |
|
3749 | 3755 | demo.prepare();
|
@@ -3825,6 +3831,10 @@ int main(int argc, char **argv) {
|
3825 | 3831 | #endif
|
3826 | 3832 | }
|
3827 | 3833 |
|
| 3834 | + demo.create_surface(); |
| 3835 | + |
| 3836 | + demo.select_physical_device(); |
| 3837 | + |
3828 | 3838 | demo.init_vk_swapchain();
|
3829 | 3839 |
|
3830 | 3840 | demo.prepare();
|
@@ -3879,6 +3889,8 @@ int main(int argc, char **argv) {
|
3879 | 3889 | // Global function invoked from NS or UI views and controllers to create demo
|
3880 | 3890 | static void demo_main(Demo &demo, void *caMetalLayer, int argc, const char *argv[]) {
|
3881 | 3891 | demo.init(argc, (char **)argv);
|
| 3892 | + demo.create_surface(); |
| 3893 | + demo.select_physical_device(); |
3882 | 3894 | demo.caMetalLayer = caMetalLayer;
|
3883 | 3895 | demo.init_vk_swapchain();
|
3884 | 3896 | demo.prepare();
|
|
0 commit comments