diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 32f860d0ed..c1c01f0b1b 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -528,7 +528,7 @@ VKGSRender::VKGSRender() : GSRender() for (auto &gpu : gpus) { - if (gpu.name() == adapter_name) + if (gpu.get_name() == adapter_name) { m_swapchain.reset(m_thread_context.createSwapChain(display, gpu)); gpu_found = true; diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index bb5879b4bb..d2071b8da8 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -276,45 +276,35 @@ namespace vk g_driver_vendor = driver_vendor::unknown; g_heap_compatible_buffer_types = 0; - const auto gpu_name = g_current_renderer->gpu().name(); - - //Radeon fails to properly handle degenerate primitives if primitive restart is enabled - //One has to choose between using degenerate primitives or primitive restart to break up lists but not both - //Polaris and newer will crash with ERROR_DEVICE_LOST - //Older GCN will work okay most of the time but also occasionally draws garbage without reason (proprietary driver only) - if (gpu_name.find("Radeon") != std::string::npos || //Proprietary driver - gpu_name.find("POLARIS") != std::string::npos || //RADV POLARIS - gpu_name.find("VEGA") != std::string::npos) //RADV VEGA + const auto gpu_name = g_current_renderer->gpu().get_name(); + switch (g_driver_vendor = g_current_renderer->gpu().get_driver_vendor()) { - g_drv_no_primitive_restart_flag = !g_cfg.video.vk.force_primitive_restart; - } - - //Radeon proprietary driver does not properly handle fence reset and can segfault during vkResetFences - //Disable fence reset for proprietary driver and delete+initialize a new fence instead - if (gpu_name.find("Radeon") != std::string::npos) - { - g_driver_vendor = driver_vendor::AMD; + case driver_vendor::AMD: + // Radeon proprietary driver does not properly handle fence reset and can segfault during vkResetFences + // Disable fence reset for proprietary driver and delete+initialize a new fence instead g_drv_disable_fence_reset = true; - } - - //Nvidia cards are easily susceptible to NaN poisoning - if (gpu_name.find("NVIDIA") != std::string::npos || gpu_name.find("GeForce") != std::string::npos) - { - g_driver_vendor = driver_vendor::NVIDIA; + // Fall through + case driver_vendor::RADV: + // Radeon fails to properly handle degenerate primitives if primitive restart is enabled + // One has to choose between using degenerate primitives or primitive restart to break up lists but not both + // Polaris and newer will crash with ERROR_DEVICE_LOST + // Older GCN will work okay most of the time but also occasionally draws garbage without reason (proprietary driver only) + if (g_driver_vendor == driver_vendor::AMD || + gpu_name.find("VEGA") != std::string::npos || + gpu_name.find("POLARIS") != std::string::npos) + { + g_drv_no_primitive_restart_flag = !g_cfg.video.vk.force_primitive_restart; + } + break; + case driver_vendor::NVIDIA: + // Nvidia cards are easily susceptible to NaN poisoning g_drv_sanitize_fp_values = true; + break; + default: + LOG_WARNING(RSX, "Unsupported device: %s", gpu_name); } - if (g_driver_vendor == driver_vendor::unknown) - { - if (gpu_name.find("RADV") != std::string::npos) - { - g_driver_vendor = driver_vendor::RADV; - } - else - { - LOG_WARNING(RSX, "Unknown driver vendor for device '%s'", gpu_name); - } - } + LOG_NOTICE(RSX, "Vulkan: Renderer initialized on device '%s'", gpu_name); { // Buffer memory tests, only useful for portability on macOS diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index 93062e1e7f..962636e895 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -400,14 +400,60 @@ namespace vk vkGetPhysicalDeviceProperties(pdev, &props); vkGetPhysicalDeviceMemoryProperties(pdev, &memory_properties); - LOG_NOTICE(RSX, "Physical device intialized. GPU=%s, driver=%u", props.deviceName, props.driverVersion); + LOG_NOTICE(RSX, "Found vulkan-compatible GPU: '%s' running on driver %s", get_name(), get_driver_version()); } - std::string name() const + std::string get_name() const { return props.deviceName; } + driver_vendor get_driver_vendor() const + { + const auto gpu_name = get_name(); + if (gpu_name.find("Radeon") != std::string::npos) + { + return driver_vendor::AMD; + } + + if (gpu_name.find("NVIDIA") != std::string::npos || gpu_name.find("GeForce") != std::string::npos) + { + return driver_vendor::NVIDIA; + } + + if (gpu_name.find("RADV") != std::string::npos) + { + return driver_vendor::RADV; + } + + return driver_vendor::unknown; + } + + std::string get_driver_version() const + { + switch (get_driver_vendor()) + { + case driver_vendor::NVIDIA: + { + // 10 + 8 + 8 + 6 + const auto major_version = VK_VERSION_MAJOR(props.driverVersion); + const auto minor_version = (props.driverVersion >> 14) & 0xff; + const auto patch = (props.driverVersion >> 6) & 0xff; + const auto revision = (props.driverVersion & 0x3f); + + return fmt::format("%u.%u.%u.%u", major_version, minor_version, patch, revision); + } + default: + { + // 10 + 10 + 12 (standard vulkan encoding created with VK_MAKE_VERSION) + return fmt::format("%u.%u.%u", + VK_VERSION_MAJOR(props.driverVersion), + VK_VERSION_MINOR(props.driverVersion), + VK_VERSION_PATCH(props.driverVersion)); + } + } + } + uint32_t get_queue_count() const { if (queue_props.size()) diff --git a/rpcs3/rpcs3qt/emu_settings.cpp b/rpcs3/rpcs3qt/emu_settings.cpp index 5f9b937060..4feccf0814 100644 --- a/rpcs3/rpcs3qt/emu_settings.cpp +++ b/rpcs3/rpcs3qt/emu_settings.cpp @@ -162,7 +162,7 @@ emu_settings::Render_Creator::Render_Creator() for (auto& gpu : gpus) { - vulkanAdapters.append(qstr(gpu.name())); + vulkanAdapters.append(qstr(gpu.get_name())); } } }