From 8e5385dce836ca5a02770e16b5785e89ea2fc80c Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Tue, 23 Apr 2024 14:33:35 -0700 Subject: [PATCH] [Impeller] Add DriverInfoVK::IsEmulator and a log dumper for driver info. For https://github.com/flutter/engine/pull/52087 --- .../renderer/backend/vulkan/driver_info_vk.cc | 92 +++++++++++++++++++ .../renderer/backend/vulkan/driver_info_vk.h | 15 +++ .../vulkan/driver_info_vk_unittests.cc | 10 ++ 3 files changed, 117 insertions(+) diff --git a/impeller/renderer/backend/vulkan/driver_info_vk.cc b/impeller/renderer/backend/vulkan/driver_info_vk.cc index 84b5249fb0a11..3dbfaacab33a8 100644 --- a/impeller/renderer/backend/vulkan/driver_info_vk.cc +++ b/impeller/renderer/backend/vulkan/driver_info_vk.cc @@ -4,6 +4,11 @@ #include "impeller/renderer/backend/vulkan/driver_info_vk.h" +#include +#include + +#include "flutter/fml/build_config.h" + namespace impeller { constexpr VendorVK IdentifyVendor(uint32_t vendor) { @@ -41,6 +46,48 @@ constexpr VendorVK IdentifyVendor(uint32_t vendor) { return VendorVK::kUnknown; } +constexpr const char* VendorToString(VendorVK vendor) { + switch (vendor) { + case VendorVK::kUnknown: + return "Unknown"; + case VendorVK::kGoogle: + return "Google"; + case VendorVK::kQualcomm: + return "Qualcomm"; + case VendorVK::kARM: + return "ARM"; + case VendorVK::kImgTec: + return "ImgTec PowerVR"; + case VendorVK::kAMD: + return "AMD"; + case VendorVK::kNvidia: + return "Nvidia"; + case VendorVK::kIntel: + return "Intel"; + case VendorVK::kMesa: + return "Mesa"; + case VendorVK::kApple: + return "Apple"; + } + FML_UNREACHABLE(); +} + +constexpr const char* DeviceTypeToString(DeviceTypeVK type) { + switch (type) { + case DeviceTypeVK::kUnknown: + return "Unknown"; + case DeviceTypeVK::kIntegratedGPU: + return "Integrated GPU"; + case DeviceTypeVK::kDiscreteGPU: + return "Discrete GPU"; + case DeviceTypeVK::kVirtualGPU: + return "Virtual GPU"; + case DeviceTypeVK::kCPU: + return "CPU"; + } + FML_UNREACHABLE(); +} + constexpr DeviceTypeVK ToDeviceType(const vk::PhysicalDeviceType& type) { switch (type) { case vk::PhysicalDeviceType::eOther: @@ -92,4 +139,49 @@ const std::string& DriverInfoVK::GetDriverName() const { return driver_name_; } +void DriverInfoVK::DumpToLog() const { + std::vector> items; + items.emplace_back("Name", driver_name_); + items.emplace_back("API Version", api_version_.ToString()); + items.emplace_back("Vendor", VendorToString(vendor_)); + items.emplace_back("Device Type", DeviceTypeToString(type_)); + items.emplace_back("Is Emulator", std::to_string(IsEmulator())); + + size_t padding = 0; + + for (const auto& item : items) { + padding = std::max(padding, item.first.size()); + } + + padding += 1; + + std::stringstream stream; + + stream << std::endl; + + stream << "--- Driver Information ------------------------------------------"; + + stream << std::endl; + + for (const auto& item : items) { + stream << "| " << std::setw(static_cast(padding)) << item.first + << std::setw(0) << ": " << item.second << std::endl; + } + + stream << "-----------------------------------------------------------------"; + + FML_LOG(IMPORTANT) << stream.str(); +} + +bool DriverInfoVK::IsEmulator() const { +#if FML_OS_ANDROID + // Google SwiftShader on Android. + if (type_ == DeviceTypeVK::kCPU && vendor_ == VendorVK::kGoogle && + driver_name_.find("SwiftShader") != std::string::npos) { + return true; + } +#endif // FML_OS_ANDROID + return false; +} + } // namespace impeller diff --git a/impeller/renderer/backend/vulkan/driver_info_vk.h b/impeller/renderer/backend/vulkan/driver_info_vk.h index 30edbf654c3d1..152b1ba3b340d 100644 --- a/impeller/renderer/backend/vulkan/driver_info_vk.h +++ b/impeller/renderer/backend/vulkan/driver_info_vk.h @@ -107,6 +107,21 @@ class DriverInfoVK { /// const std::string& GetDriverName() const; + //---------------------------------------------------------------------------- + /// @brief Dumps the current driver info to the log. + /// + void DumpToLog() const; + + //---------------------------------------------------------------------------- + /// @brief Determines if the driver represents an emulator. There is no + /// definitive way to tell if a driver is an emulator and drivers + /// don't self identify as emulators. So take this information + /// with a pinch of salt. + /// + /// @return True if emulator, False otherwise. + /// + bool IsEmulator() const; + private: bool is_valid_ = false; Version api_version_; diff --git a/impeller/renderer/backend/vulkan/driver_info_vk_unittests.cc b/impeller/renderer/backend/vulkan/driver_info_vk_unittests.cc index f7964ce8fffde..aacced65e6e64 100644 --- a/impeller/renderer/backend/vulkan/driver_info_vk_unittests.cc +++ b/impeller/renderer/backend/vulkan/driver_info_vk_unittests.cc @@ -23,4 +23,14 @@ TEST_P(DriverInfoVKTest, CanQueryDriverInfo) { ASSERT_NE(driver_info->GetDriverName(), ""); } +TEST_P(DriverInfoVKTest, CanDumpToLog) { + ASSERT_TRUE(GetContext()); + const auto& driver_info = + SurfaceContextVK::Cast(*GetContext()).GetParent().GetDriverInfo(); + ASSERT_NE(driver_info, nullptr); + fml::testing::LogCapture log; + driver_info->DumpToLog(); + ASSERT_TRUE(log.str().find("Driver Information") != std::string::npos); +} + } // namespace impeller::testing