Edit

kc3-lang/angle/src/gpu_info_util/SystemInfo_android.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2018-11-27 11:34:27
    Hash : b980c563
    Message : Reformat all cpp and h files. This applies git cl format --full to all ANGLE sources. Bug: angleproject:2986 Change-Id: Ib504e618c1589332a37e97696cdc3515d739308f Reviewed-on: https://chromium-review.googlesource.com/c/1351367 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>

  • src/gpu_info_util/SystemInfo_android.cpp
  • //
    // 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("libvulkan.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_vkEnumerateInstanceVersion>(
                    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;
    };
    
    ANGLE_FORMAT_PRINTF(1, 2)
    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;
        if (!pfnEnumeratePhysicalDevices ||
            pfnEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr) != VK_SUCCESS)
        {
            return false;
        }
        std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
        if (pfnEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data()) !=
            VK_SUCCESS)
        {
            return false;
        }
    
        // If we get to here, we will likely provide a valid answer (unless an unknown vendorID):
        info->gpus.resize(physicalDeviceCount);
    
        for (uint32_t i = 0; i < physicalDeviceCount; i++)
        {
            VkPhysicalDeviceProperties properties;
            pfnGetPhysicalDeviceProperties(physicalDevices[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);
                    gpu.detailedDriverVersion.major = properties.driverVersion;
                    break;
                case kVendorID_ARM:
                    gpu.driverVendor                = "Arm Holdings";
                    gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
                    gpu.detailedDriverVersion.major = properties.driverVersion;
                    break;
                case kVendorID_ImgTec:
                    gpu.driverVendor                = "Imagination Technologies Limited";
                    gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
                    gpu.detailedDriverVersion.major = properties.driverVersion;
                    break;
                case kVendorID_Intel:
                    gpu.driverVendor                = "Intel Corporation";
                    gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
                    gpu.detailedDriverVersion.major = 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);
                    gpu.detailedDriverVersion.major    = properties.driverVersion >> 22;
                    gpu.detailedDriverVersion.minor    = (properties.driverVersion >> 14) & 0xFF;
                    gpu.detailedDriverVersion.subMinor = (properties.driverVersion >> 6) & 0xFF;
                    gpu.detailedDriverVersion.patch    = 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);
                        gpu.detailedDriverVersion.major    = properties.driverVersion >> 22;
                        gpu.detailedDriverVersion.minor    = (properties.driverVersion >> 12) & 0x3FF;
                        gpu.detailedDriverVersion.subMinor = properties.driverVersion & 0xFFF;
                    }
                    else
                    {
                        gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
                        gpu.detailedDriverVersion.major = properties.driverVersion;
                    }
                    break;
                case kVendorID_Vivante:
                    gpu.driverVendor                = "Vivante";
                    gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
                    gpu.detailedDriverVersion.major = properties.driverVersion;
                    break;
                case kVendorID_VeriSilicon:
                    gpu.driverVendor                = "VeriSilicon";
                    gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
                    gpu.detailedDriverVersion.major = properties.driverVersion;
                    break;
                case kVendorID_Kazan:
                    gpu.driverVendor                = "Kazan Software";
                    gpu.driverVersion               = FormatString("0x%x", properties.driverVersion);
                    gpu.detailedDriverVersion.major = properties.driverVersion;
                    break;
                default:
                    return false;
            }
            gpu.driverDate = "";
        }
    
        return true;
    }
    
    }  // namespace angle