blob: 3dbfaacab33a829f9a25782690e81a9cecaea136 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "impeller/renderer/backend/vulkan/driver_info_vk.h"
#include <iomanip>
#include <sstream>
#include "flutter/fml/build_config.h"
namespace impeller {
constexpr VendorVK IdentifyVendor(uint32_t vendor) {
// Check if the vendor has a PCI ID:
// https://pcisig.com/membership/member-companies
switch (vendor) {
case 0x1AE0:
return VendorVK::kGoogle;
case 0x168C:
case 0x17CB:
case 0x1969:
case 0x5143:
return VendorVK::kQualcomm;
case 0x13B5:
return VendorVK::kARM;
case 0x1010:
return VendorVK::kImgTec;
case 0x1002:
case 0x1022:
return VendorVK::kAMD;
case 0x10DE:
return VendorVK::kNvidia;
case 0x8086: // :)
return VendorVK::kIntel;
case 0x106B:
return VendorVK::kApple;
}
// Check if the ID is a known Khronos vendor.
switch (vendor) {
case VK_VENDOR_ID_MESA:
return VendorVK::kMesa;
// There are others but have never been observed. These can be added as
// needed.
}
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:
return DeviceTypeVK::kUnknown;
case vk::PhysicalDeviceType::eIntegratedGpu:
return DeviceTypeVK::kIntegratedGPU;
case vk::PhysicalDeviceType::eDiscreteGpu:
return DeviceTypeVK::kDiscreteGPU;
case vk::PhysicalDeviceType::eVirtualGpu:
return DeviceTypeVK::kVirtualGPU;
case vk::PhysicalDeviceType::eCpu:
return DeviceTypeVK::kCPU;
break;
}
return DeviceTypeVK::kUnknown;
}
DriverInfoVK::DriverInfoVK(const vk::PhysicalDevice& device) {
auto props = device.getProperties();
api_version_ = Version{VK_API_VERSION_MAJOR(props.apiVersion),
VK_API_VERSION_MINOR(props.apiVersion),
VK_API_VERSION_PATCH(props.apiVersion)};
vendor_ = IdentifyVendor(props.vendorID);
if (vendor_ == VendorVK::kUnknown) {
FML_LOG(WARNING) << "Unknown GPU Driver Vendor: " << props.vendorID
<< ". This is not an error.";
}
type_ = ToDeviceType(props.deviceType);
if (props.deviceName.data() != nullptr) {
driver_name_ = props.deviceName.data();
}
}
DriverInfoVK::~DriverInfoVK() = default;
const Version& DriverInfoVK::GetAPIVersion() const {
return api_version_;
}
const VendorVK& DriverInfoVK::GetVendor() const {
return vendor_;
}
const DeviceTypeVK& DriverInfoVK::GetDeviceType() const {
return type_;
}
const std::string& DriverInfoVK::GetDriverName() const {
return driver_name_;
}
void DriverInfoVK::DumpToLog() const {
std::vector<std::pair<std::string, std::string>> 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<int>(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