Edit

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

Branch :

  • Show log

    Commit

  • Author : Shahbaz Youssefi
    Date : 2018-10-18 13:04:40
    Hash : a390ebd9
    Message : Add compiler printf attribute to relevant functions Relands 27a472c60 with reinterpret_cast changed to C-style cast to support types that are pointers on some platforms and integers on others. This commit includes fixes to undefined behavior caught by this attribute. The following changes have been made: - 0x%0.8p is changed to %016 PRIxPTR. Both 0 and . have undefined behavior with p. Additionally, %p already prints 0x with both gcc and clang. This results in a small output change: void *x = (void *)0x1234; void *y = (void *)0x1234567890abcdef; printf("|%0.8p|\n", x); printf("|%0.8p|\n", y); printf("|%016" PRIxPTR "|\n", (uintptr_t)x); printf("|%016" PRIxPTR "|\n", (uintptr_t)y); prints: |0x00001234| |0x1234567890abcdef| |0x0000000000001234| |0x1234567890abcdef| - %d used for GLintptr, GLsizeiptr, EGLTime and EGLnsecsANDROID is changed to %llu and the relevant argument is cast to unsigned long long. This is due to these types being typedefs to unknown types (on Linux for example, these are unsigned long, and my guess would be unsigned long long on Windows where long is 32 bits). - %llu is used for GLuint64, which could be unsigned long (as is on Linux). Those arguments are cast to unsigned long long. - %p is used for some EGLNative types, but those types may not be a pointer. Those arguments are cast to uintptr_t and printed as above. Bug: angleproject:2928 Change-Id: Idf9f705c3d00f69e41e7603453016276a2e13a64 Reviewed-on: https://chromium-review.googlesource.com/c/1300913 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: 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