Commit d07c52e2 by Ian Elliott Committed by Commit Bot

Initial Android implementation of GetSystemInfo

Change-Id: Ia44413aa94906b89d4981063600cd3de0edacee8 Reviewed-on: https://chromium-review.googlesource.com/1108454 Commit-Queue: Ian Elliott <ianelliott@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 7c37ca18
...@@ -251,6 +251,10 @@ static_library("angle_gpu_info_util") { ...@@ -251,6 +251,10 @@ static_library("angle_gpu_info_util") {
libs = [] libs = []
defines = [] defines = []
if (is_android) {
sources += [ "src/gpu_info_util/SystemInfo_android.cpp" ]
}
if (is_win) { if (is_win) {
sources += sources +=
rebase_path(gles_gypi.libangle_gpu_info_util_win_sources, ".", "src") rebase_path(gles_gypi.libangle_gpu_info_util_win_sources, ".", "src")
......
...@@ -34,6 +34,21 @@ bool IsAMD(VendorID vendorId) ...@@ -34,6 +34,21 @@ bool IsAMD(VendorID vendorId)
return vendorId == kVendorID_AMD; return vendorId == kVendorID_AMD;
} }
bool IsARM(VendorID vendorId)
{
return vendorId == kVendorID_ARM;
}
bool IsImgTec(VendorID vendorId)
{
return vendorId == kVendorID_ImgTec;
}
bool IsKazan(VendorID vendorId)
{
return vendorId == kVendorID_Kazan;
}
bool IsIntel(VendorID vendorId) bool IsIntel(VendorID vendorId)
{ {
return vendorId == kVendorID_Intel; return vendorId == kVendorID_Intel;
...@@ -49,6 +64,16 @@ bool IsQualcomm(VendorID vendorId) ...@@ -49,6 +64,16 @@ bool IsQualcomm(VendorID vendorId)
return vendorId == kVendorID_Qualcomm; return vendorId == kVendorID_Qualcomm;
} }
bool IsVeriSilicon(VendorID vendorId)
{
return vendorId == kVendorID_VeriSilicon;
}
bool IsVivante(VendorID vendorId)
{
return vendorId == kVendorID_Vivante;
}
bool ParseAMDBrahmaDriverVersion(const std::string &content, std::string *version) bool ParseAMDBrahmaDriverVersion(const std::string &content, std::string *version)
{ {
const size_t begin = content.find_first_of("0123456789"); const size_t begin = content.find_first_of("0123456789");
......
...@@ -68,15 +68,27 @@ bool GetSystemInfo(SystemInfo *info); ...@@ -68,15 +68,27 @@ bool GetSystemInfo(SystemInfo *info);
// Known PCI vendor IDs // Known PCI vendor IDs
constexpr VendorID kVendorID_AMD = 0x1002; constexpr VendorID kVendorID_AMD = 0x1002;
constexpr VendorID kVendorID_ARM = 0x13B5;
constexpr VendorID kVendorID_ImgTec = 0x1010;
constexpr VendorID kVendorID_Intel = 0x8086; constexpr VendorID kVendorID_Intel = 0x8086;
constexpr VendorID kVendorID_Nvidia = 0x10DE; constexpr VendorID kVendorID_Nvidia = 0x10DE;
constexpr VendorID kVendorID_Qualcomm = 0x5143; constexpr VendorID kVendorID_Qualcomm = 0x5143;
// Known non-PCI (i.e. Khronos-registered) vendor IDs
constexpr VendorID kVendorID_Vivante = 0x10001;
constexpr VendorID kVendorID_VeriSilicon = 0x10002;
constexpr VendorID kVendorID_Kazan = 0x10003;
// Predicates on vendor IDs // Predicates on vendor IDs
bool IsAMD(VendorID vendorId); bool IsAMD(VendorID vendorId);
bool IsARM(VendorID vendorId);
bool IsImgTec(VendorID vendorId);
bool IsIntel(VendorID vendorId); bool IsIntel(VendorID vendorId);
bool IsKazan(VendorID vendorId);
bool IsNvidia(VendorID vendorId); bool IsNvidia(VendorID vendorId);
bool IsQualcomm(VendorID vendorId); bool IsQualcomm(VendorID vendorId);
bool IsVeriSilicon(VendorID vendorId);
bool IsVivante(VendorID vendorId);
} // namespace angle } // namespace angle
......
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SystemInfo_android.cpp: implementation of the Android-specific parts of SystemInfo.h
#include <dlfcn.h>
#include <vulkan/vulkan.h>
#include "gpu_info_util/SystemInfo_internal.h"
#include <cstring>
#include <fstream>
#include "common/angleutils.h"
#include "common/debug.h"
namespace angle
{
class VulkanLibrary final : NonCopyable
{
public:
VulkanLibrary() {}
~VulkanLibrary()
{
if (mInstance != VK_NULL_HANDLE)
{
PFN_vkDestroyInstance pfnDestroyInstance =
reinterpret_cast<PFN_vkDestroyInstance>(dlsym(mLibVulkan, "vkDestroyInstance"));
if (pfnDestroyInstance)
{
pfnDestroyInstance(mInstance, nullptr);
}
}
if (mLibVulkan)
dlclose(mLibVulkan);
}
VkInstance getVulkanInstance()
{
// Find the system's Vulkan library and open it:
mLibVulkan = dlopen("mLibVulkan.so", RTLD_NOW | RTLD_LOCAL);
if (!mLibVulkan)
{
// If Vulkan doesn't exist, bail-out early:
return VK_NULL_HANDLE;
}
// Determine the available Vulkan instance version:
uint32_t instanceVersion = VK_API_VERSION_1_0;
#if defined(VK_VERSION_1_1)
PFN_vkEnumerateInstanceVersion pfnEnumerateInstanceVersion =
reinterpret_cast<PFN_vkCreateInstance>(dlsym(mLibVulkan, "vkEnumerateInstanceVersion"));
if (!pfnEnumerateInstanceVersion ||
pfnEnumerateInstanceVersion(&instanceVersion) != VK_SUCCESS)
{
instanceVersion = VK_API_VERSION_1_0;
}
#endif // VK_VERSION_1_1
// Create a Vulkan instance:
VkApplicationInfo appInfo;
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pNext = nullptr;
appInfo.pApplicationName = "";
appInfo.applicationVersion = 1;
appInfo.pEngineName = "";
appInfo.engineVersion = 1;
appInfo.apiVersion = instanceVersion;
VkInstanceCreateInfo createInstanceInfo;
createInstanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInstanceInfo.pNext = nullptr;
createInstanceInfo.flags = 0;
createInstanceInfo.pApplicationInfo = &appInfo;
createInstanceInfo.enabledLayerCount = 0;
createInstanceInfo.ppEnabledLayerNames = nullptr;
createInstanceInfo.enabledExtensionCount = 0;
createInstanceInfo.ppEnabledExtensionNames = nullptr;
PFN_vkCreateInstance pfnCreateInstance =
reinterpret_cast<PFN_vkCreateInstance>(dlsym(mLibVulkan, "vkCreateInstance"));
if (!pfnCreateInstance ||
pfnCreateInstance(&createInstanceInfo, nullptr, &mInstance) != VK_SUCCESS)
{
return VK_NULL_HANDLE;
}
return mInstance;
}
void *gpa(std::string fn) { return dlsym(mLibVulkan, fn.c_str()); }
#define GPA(ob, type, fn) reinterpret_cast<type>(ob.gpa(fn))
private:
void *mLibVulkan = nullptr;
VkInstance mInstance = VK_NULL_HANDLE;
};
std::string FormatString(const char *fmt, ...)
{
va_list vararg;
va_start(vararg, fmt);
std::vector<char> buffer(512);
size_t len = FormatStringIntoVector(fmt, vararg, buffer);
va_end(vararg);
return std::string(&buffer[0], len);
}
bool GetSystemInfo(SystemInfo *info)
{
// This implementation builds on top of the Vulkan API, but cannot assume the existence of the
// Vulkan library. ANGLE can be installed on versions of Android as old as Ice Cream Sandwich.
// Therefore, we need to use dlopen()/dlsym() in order to see if Vulkan is installed on the
// system, and if so, to use it:
VulkanLibrary vkLibrary;
VkInstance instance = vkLibrary.getVulkanInstance();
if (instance == VK_NULL_HANDLE)
{
// If Vulkan doesn't exist, bail-out early:
return false;
}
// Enumerate the Vulkan physical devices, which are ANGLE gpus:
PFN_vkEnumeratePhysicalDevices pfnEnumeratePhysicalDevices =
GPA(vkLibrary, PFN_vkEnumeratePhysicalDevices, "vkEnumeratePhysicalDevices");
PFN_vkGetPhysicalDeviceProperties pfnGetPhysicalDeviceProperties =
GPA(vkLibrary, PFN_vkGetPhysicalDeviceProperties, "vkGetPhysicalDeviceProperties");
uint32_t physicalDeviceCount = 0;
VkPhysicalDevice *pPhysicalDevices = nullptr;
if (!pfnEnumeratePhysicalDevices ||
pfnEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr) != VK_SUCCESS)
{
return false;
}
std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
info->gpus.resize(physicalDeviceCount);
if (pfnEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data()) !=
VK_SUCCESS)
{
return false;
}
for (uint32_t i = 0; i < physicalDeviceCount; i++)
{
VkPhysicalDeviceProperties properties;
pfnGetPhysicalDeviceProperties(pPhysicalDevices[i], &properties);
// Fill in data for a given physical device (a.k.a. gpu):
GPUDeviceInfo &gpu = info->gpus[i];
gpu.vendorId = properties.vendorID;
gpu.deviceId = properties.deviceID;
// Need to parse/re-format properties.driverVersion.
//
// TODO(ianelliott): Determine the formatting used for each vendor
// (http://anglebug.com/2677)
switch (properties.vendorID)
{
case kVendorID_AMD:
gpu.driverVendor = "Advanced Micro Devices, Inc";
gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
break;
case kVendorID_ARM:
gpu.driverVendor = "Arm Holdings";
gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
break;
case kVendorID_ImgTec:
gpu.driverVendor = "Imagination Technologies Limited";
gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
break;
case kVendorID_Intel:
gpu.driverVendor = "Intel Corporation";
gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
break;
case kVendorID_Nvidia:
gpu.driverVendor = "NVIDIA Corporation";
gpu.driverVersion = FormatString("%d.%d.%d.%d", properties.driverVersion >> 22,
(properties.driverVersion >> 14) & 0XFF,
(properties.driverVersion >> 6) & 0XFF,
properties.driverVersion & 0x3F);
break;
case kVendorID_Qualcomm:
gpu.driverVendor = "Qualcomm Technologies, Inc";
if (properties.driverVersion & 0x80000000)
{
gpu.driverVersion = FormatString("%d.%d.%d", properties.driverVersion >> 22,
(properties.driverVersion >> 12) & 0X3FF,
properties.driverVersion & 0xFFF);
}
else
{
gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
}
break;
case kVendorID_Vivante:
gpu.driverVendor = "Vivante";
gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
break;
case kVendorID_VeriSilicon:
gpu.driverVendor = "VeriSilicon";
gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
break;
case kVendorID_Kazan:
gpu.driverVendor = "Kazan Software";
gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
break;
default:
return false;
}
gpu.driverDate = "";
}
return true;
}
} // namespace angle
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment