Path: blob/main_old/src/gpu_info_util/SystemInfo_vulkan.cpp
1693 views
//1// Copyright 2020 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// SystemInfo_vulkan.cpp: Generic vulkan implementation of SystemInfo.h7// TODO: Use VK_KHR_driver_properties. http://anglebug.com/510389#include <vulkan/vulkan.h>10#include "gpu_info_util/SystemInfo_internal.h"1112#include <cstring>13#include <fstream>1415#include "common/angleutils.h"16#include "common/debug.h"17#include "common/system_utils.h"18#include "common/vulkan/libvulkan_loader.h"1920namespace angle21{22class VulkanLibrary final : NonCopyable23{24public:25VulkanLibrary() = default;2627~VulkanLibrary()28{29if (mInstance != VK_NULL_HANDLE)30{31auto pfnDestroyInstance = getProc<PFN_vkDestroyInstance>("vkDestroyInstance");32if (pfnDestroyInstance)33{34pfnDestroyInstance(mInstance, nullptr);35}36}37}3839VkInstance getVulkanInstance()40{41mLibVulkan = vk::OpenLibVulkan();42if (!mLibVulkan)43{44// If Vulkan doesn't exist, bail-out early:45return VK_NULL_HANDLE;46}4748// Determine the available Vulkan instance version:49uint32_t instanceVersion = VK_API_VERSION_1_0;50#if defined(VK_VERSION_1_1)51auto pfnEnumerateInstanceVersion =52getProc<PFN_vkEnumerateInstanceVersion>("vkEnumerateInstanceVersion");53if (!pfnEnumerateInstanceVersion ||54pfnEnumerateInstanceVersion(&instanceVersion) != VK_SUCCESS)55{56instanceVersion = VK_API_VERSION_1_0;57}58#endif // VK_VERSION_1_15960// Create a Vulkan instance:61VkApplicationInfo appInfo;62appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;63appInfo.pNext = nullptr;64appInfo.pApplicationName = "";65appInfo.applicationVersion = 1;66appInfo.pEngineName = "";67appInfo.engineVersion = 1;68appInfo.apiVersion = instanceVersion;6970VkInstanceCreateInfo createInstanceInfo;71createInstanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;72createInstanceInfo.pNext = nullptr;73createInstanceInfo.flags = 0;74createInstanceInfo.pApplicationInfo = &appInfo;75createInstanceInfo.enabledLayerCount = 0;76createInstanceInfo.ppEnabledLayerNames = nullptr;77createInstanceInfo.enabledExtensionCount = 0;78createInstanceInfo.ppEnabledExtensionNames = nullptr;7980auto pfnCreateInstance = getProc<PFN_vkCreateInstance>("vkCreateInstance");81if (!pfnCreateInstance ||82pfnCreateInstance(&createInstanceInfo, nullptr, &mInstance) != VK_SUCCESS)83{84return VK_NULL_HANDLE;85}8687return mInstance;88}8990template <typename Func>91Func getProc(const char *fn) const92{93return reinterpret_cast<Func>(mLibVulkan->getSymbol(fn));94}9596private:97std::unique_ptr<Library> mLibVulkan = nullptr;98VkInstance mInstance = VK_NULL_HANDLE;99};100101ANGLE_FORMAT_PRINTF(1, 2)102std::string FormatString(const char *fmt, ...)103{104va_list vararg;105va_start(vararg, fmt);106107std::vector<char> buffer;108size_t len = FormatStringIntoVector(fmt, vararg, buffer);109va_end(vararg);110111return std::string(&buffer[0], len);112}113114bool GetSystemInfoVulkan(SystemInfo *info)115{116// This implementation builds on top of the Vulkan API, but cannot assume the existence of the117// Vulkan library. ANGLE can be installed on versions of Android as old as Ice Cream Sandwich.118// Therefore, we need to use dlopen()/dlsym() in order to see if Vulkan is installed on the119// system, and if so, to use it:120VulkanLibrary vkLibrary;121VkInstance instance = vkLibrary.getVulkanInstance();122if (instance == VK_NULL_HANDLE)123{124// If Vulkan doesn't exist, bail-out early:125return false;126}127128// Enumerate the Vulkan physical devices, which are ANGLE gpus:129auto pfnEnumeratePhysicalDevices =130vkLibrary.getProc<PFN_vkEnumeratePhysicalDevices>("vkEnumeratePhysicalDevices");131auto pfnGetPhysicalDeviceProperties =132vkLibrary.getProc<PFN_vkGetPhysicalDeviceProperties>("vkGetPhysicalDeviceProperties");133uint32_t physicalDeviceCount = 0;134if (!pfnEnumeratePhysicalDevices || !pfnGetPhysicalDeviceProperties ||135pfnEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr) != VK_SUCCESS)136{137return false;138}139std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);140if (pfnEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data()) !=141VK_SUCCESS)142{143return false;144}145146// If we get to here, we will likely provide a valid answer (unless an unknown vendorID):147info->gpus.resize(physicalDeviceCount);148149for (uint32_t i = 0; i < physicalDeviceCount; i++)150{151VkPhysicalDeviceProperties properties;152pfnGetPhysicalDeviceProperties(physicalDevices[i], &properties);153// Fill in data for a given physical device (a.k.a. gpu):154GPUDeviceInfo &gpu = info->gpus[i];155gpu.vendorId = properties.vendorID;156gpu.deviceId = properties.deviceID;157// Need to parse/re-format properties.driverVersion.158//159// TODO(ianelliott): Determine the formatting used for each vendor160// (http://anglebug.com/2677)161switch (properties.vendorID)162{163case kVendorID_AMD:164gpu.driverVendor = "Advanced Micro Devices, Inc";165gpu.driverVersion = FormatString("0x%x", properties.driverVersion);166gpu.detailedDriverVersion.major = properties.driverVersion;167break;168case kVendorID_ARM:169gpu.driverVendor = "Arm Holdings";170gpu.driverVersion = FormatString("0x%x", properties.driverVersion);171gpu.detailedDriverVersion.major = properties.driverVersion;172break;173case kVendorID_Broadcom:174gpu.driverVendor = "Broadcom";175gpu.driverVersion = FormatString("0x%x", properties.driverVersion);176gpu.detailedDriverVersion.major = properties.driverVersion;177break;178case kVendorID_ImgTec:179gpu.driverVendor = "Imagination Technologies Limited";180gpu.driverVersion = FormatString("0x%x", properties.driverVersion);181gpu.detailedDriverVersion.major = properties.driverVersion;182break;183case kVendorID_Intel:184gpu.driverVendor = "Intel Corporation";185gpu.driverVersion = FormatString("0x%x", properties.driverVersion);186gpu.detailedDriverVersion.major = properties.driverVersion;187break;188case kVendorID_Kazan:189gpu.driverVendor = "Kazan Software";190gpu.driverVersion = FormatString("0x%x", properties.driverVersion);191gpu.detailedDriverVersion.major = properties.driverVersion;192break;193case kVendorID_NVIDIA:194gpu.driverVendor = "NVIDIA Corporation";195gpu.driverVersion = FormatString("%d.%d.%d.%d", properties.driverVersion >> 22,196(properties.driverVersion >> 14) & 0XFF,197(properties.driverVersion >> 6) & 0XFF,198properties.driverVersion & 0x3F);199gpu.detailedDriverVersion.major = properties.driverVersion >> 22;200gpu.detailedDriverVersion.minor = (properties.driverVersion >> 14) & 0xFF;201gpu.detailedDriverVersion.subMinor = (properties.driverVersion >> 6) & 0xFF;202gpu.detailedDriverVersion.patch = properties.driverVersion & 0x3F;203break;204case kVendorID_Qualcomm:205gpu.driverVendor = "Qualcomm Technologies, Inc";206if (properties.driverVersion & 0x80000000)207{208gpu.driverVersion = FormatString("%d.%d.%d", properties.driverVersion >> 22,209(properties.driverVersion >> 12) & 0X3FF,210properties.driverVersion & 0xFFF);211gpu.detailedDriverVersion.major = properties.driverVersion >> 22;212gpu.detailedDriverVersion.minor = (properties.driverVersion >> 12) & 0x3FF;213gpu.detailedDriverVersion.subMinor = properties.driverVersion & 0xFFF;214}215else216{217gpu.driverVersion = FormatString("0x%x", properties.driverVersion);218gpu.detailedDriverVersion.major = properties.driverVersion;219}220break;221case kVendorID_VeriSilicon:222gpu.driverVendor = "VeriSilicon";223gpu.driverVersion = FormatString("0x%x", properties.driverVersion);224gpu.detailedDriverVersion.major = properties.driverVersion;225break;226case kVendorID_Vivante:227gpu.driverVendor = "Vivante";228gpu.driverVersion = FormatString("0x%x", properties.driverVersion);229gpu.detailedDriverVersion.major = properties.driverVersion;230break;231default:232return false;233}234gpu.driverDate = "";235}236237return true;238}239240} // namespace angle241242243