From db810956ec74b094c006cddf6854d626e0991221 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 19 Sep 2017 21:11:33 +1000 Subject: [PATCH] Vulkan: Provide a more accurate method of detecting drivers/vendors This is needed to differentiate between the open-source Mesa drivers and their binary counterparts for Intel and AMD. --- .../VideoBackends/Vulkan/VulkanContext.cpp | 84 +++++++++++++++++-- .../Core/VideoBackends/Vulkan/VulkanContext.h | 1 + Source/Core/VideoCommon/DriverDetails.cpp | 30 ------- Source/Core/VideoCommon/DriverDetails.h | 3 - 4 files changed, 80 insertions(+), 38 deletions(-) diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp index f9c254a04d..495bdaf519 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp @@ -352,11 +352,7 @@ std::unique_ptr VulkanContext::Create(VkInstance instance, VkPhys std::unique_ptr context = std::make_unique(instance, gpu); // Initialize DriverDetails so that we can check for bugs to disable features if needed. - DriverDetails::Init(DriverDetails::API_VULKAN, - DriverDetails::TranslatePCIVendorID(context->m_device_properties.vendorID), - DriverDetails::DRIVER_UNKNOWN, - static_cast(context->m_device_properties.driverVersion), - DriverDetails::Family::UNKNOWN); + context->InitDriverDetails(); // Enable debug reports if the "Host GPU" log category is enabled. if (enable_debug_reports) @@ -761,4 +757,82 @@ u32 VulkanContext::GetReadbackMemoryType(u32 bits, bool* is_coherent, bool* is_c return type_index; } + +void VulkanContext::InitDriverDetails() +{ + DriverDetails::Vendor vendor; + DriverDetails::Driver driver; + + // String comparisons aren't ideal, but there doesn't seem to be any other way to tell + // which vendor a driver is for. These names are based on the reports submitted to + // vulkan.gpuinfo.org, as of 19/09/2017. + std::string device_name = m_device_properties.deviceName; + u32 vendor_id = m_device_properties.vendorID; + if (vendor_id == 0x10DE) + { + // Currently, there is only the official NV binary driver. + // "NVIDIA" does not appear in the device name. + vendor = DriverDetails::VENDOR_NVIDIA; + driver = DriverDetails::DRIVER_NVIDIA; + } + else if (vendor_id == 0x1002 || vendor_id == 0x1022 || + device_name.find("AMD") != std::string::npos) + { + // RADV always advertises its name in the device string. + // If not RADV, assume the AMD binary driver. + if (device_name.find("RADV") != std::string::npos) + { + vendor = DriverDetails::VENDOR_MESA; + driver = DriverDetails::DRIVER_R600; + } + else + { + vendor = DriverDetails::VENDOR_ATI; + driver = DriverDetails::DRIVER_ATI; + } + } + else if (vendor_id == 0x8086 || vendor_id == 0x8087 || + device_name.find("Intel") != std::string::npos) + { +// Apart from the driver version, Intel does not appear to provide a way to +// differentiate between anv and the binary driver (Skylake+). Assume to be +// using anv if we not running on Windows. +#ifdef WIN32 + vendor = DriverDetails::VENDOR_INTEL; + driver = DriverDetails::DRIVER_INTEL; +#else + vendor = DriverDetails::VENDOR_MESA; + driver = DriverDetails::DRIVER_I965; +#endif + } + else if (vendor_id == 0x5143 || device_name.find("Adreno") != std::string::npos) + { + // Currently only the Qualcomm binary driver exists for Adreno. + vendor = DriverDetails::VENDOR_QUALCOMM; + driver = DriverDetails::DRIVER_QUALCOMM; + } + else if (vendor_id == 0x13B6 || device_name.find("Mali") != std::string::npos) + { + // Currently only the ARM binary driver exists for Mali. + vendor = DriverDetails::VENDOR_ARM; + driver = DriverDetails::DRIVER_ARM; + } + else if (vendor_id == 0x1010 || device_name.find("PowerVR") != std::string::npos) + { + // Currently only the binary driver exists for PowerVR. + vendor = DriverDetails::VENDOR_IMGTEC; + driver = DriverDetails::DRIVER_IMGTEC; + } + else + { + WARN_LOG(VIDEO, "Unknown Vulkan driver vendor, please report it to us."); + WARN_LOG(VIDEO, "Vendor ID: 0x%X, Device Name: %s", vendor_id, device_name.c_str()); + vendor = DriverDetails::VENDOR_UNKNOWN; + driver = DriverDetails::DRIVER_UNKNOWN; + } + + DriverDetails::Init(DriverDetails::API_VULKAN, vendor, driver, + static_cast(m_device_properties.driverVersion), + DriverDetails::Family::UNKNOWN); +} } diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.h b/Source/Core/VideoBackends/Vulkan/VulkanContext.h index fd504560b8..1e9841c029 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.h +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.h @@ -114,6 +114,7 @@ private: bool SelectDeviceExtensions(ExtensionList* extension_list, bool enable_surface); bool SelectDeviceFeatures(); bool CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer); + void InitDriverDetails(); VkInstance m_instance = VK_NULL_HANDLE; VkPhysicalDevice m_physical_device = VK_NULL_HANDLE; diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp index 8fd990395d..ce595738bc 100644 --- a/Source/Core/VideoCommon/DriverDetails.cpp +++ b/Source/Core/VideoCommon/DriverDetails.cpp @@ -165,34 +165,4 @@ bool HasBug(Bug bug) return false; return it->second.m_hasbug; } - -Vendor TranslatePCIVendorID(u32 vendor_id) -{ - switch (vendor_id) - { - case 0x10DE: - return VENDOR_NVIDIA; - - case 0x1002: - case 0x1022: - return VENDOR_ATI; - - case 0x8086: - case 0x8087: - return VENDOR_INTEL; - - // TODO: Is this correct for Mali? - case 0x13B6: - return VENDOR_ARM; - - case 0x5143: - return VENDOR_QUALCOMM; - - case 0x1010: - return VENDOR_IMGTEC; - - default: - return VENDOR_UNKNOWN; - } -} } diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h index bc96ee2aab..7a92ffcc61 100644 --- a/Source/Core/VideoCommon/DriverDetails.h +++ b/Source/Core/VideoCommon/DriverDetails.h @@ -285,7 +285,4 @@ void Init(API api, Vendor vendor, Driver driver, const double version, const Fam // Once Vendor and driver version is set, this will return if it has the applicable bug passed to // it. bool HasBug(Bug bug); - -// Attempts to map a PCI vendor ID to our Vendor enumeration -Vendor TranslatePCIVendorID(u32 vendor_id); }