Path: blob/main_old/src/gpu_info_util/SystemInfo_libpci.cpp
1693 views
//1// Copyright 2013 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_libpci.cpp: implementation of the libPCI-specific parts of SystemInfo.h78#include "gpu_info_util/SystemInfo_internal.h"910#include <dlfcn.h>11#include <pci/pci.h>12#include <unistd.h>1314#include "common/angleutils.h"15#include "common/debug.h"1617#if !defined(GPU_INFO_USE_LIBPCI)18# error SystemInfo_libpci.cpp compiled without GPU_INFO_USE_LIBPCI19#endif2021namespace angle22{2324namespace25{2627struct LibPCI : private angle::NonCopyable28{29LibPCI()30{31if (access("/sys/bus/pci/", F_OK) != 0 && access("/sys/bs/pci_express/", F_OK) != 0)32{33return;34}3536mHandle = dlopen("libpci.so.3", RTLD_LAZY);3738if (mHandle == nullptr)39{40mHandle = dlopen("libpci.so", RTLD_LAZY);41}4243if (mHandle == nullptr)44{45return;46}4748mValid =49(Alloc = reinterpret_cast<decltype(Alloc)>(dlsym(mHandle, "pci_alloc"))) != nullptr &&50(Init = reinterpret_cast<decltype(Init)>(dlsym(mHandle, "pci_init"))) != nullptr &&51(Cleanup = reinterpret_cast<decltype(Cleanup)>(dlsym(mHandle, "pci_cleanup"))) !=52nullptr &&53(ScanBus = reinterpret_cast<decltype(ScanBus)>(dlsym(mHandle, "pci_scan_bus"))) !=54nullptr &&55(FillInfo = reinterpret_cast<decltype(FillInfo)>(dlsym(mHandle, "pci_fill_info"))) !=56nullptr &&57(LookupName = reinterpret_cast<decltype(LookupName)>(58dlsym(mHandle, "pci_lookup_name"))) != nullptr &&59(PCIReadByte = reinterpret_cast<decltype(PCIReadByte)>(60dlsym(mHandle, "pci_read_byte"))) != nullptr;61}6263bool IsValid() const { return mValid; }6465~LibPCI()66{67if (mHandle != nullptr)68{69dlclose(mHandle);70}71}7273decltype(&::pci_alloc) Alloc = nullptr;74decltype(&::pci_init) Init = nullptr;75decltype(&::pci_cleanup) Cleanup = nullptr;76decltype(&::pci_scan_bus) ScanBus = nullptr;77decltype(&::pci_fill_info) FillInfo = nullptr;78decltype(&::pci_lookup_name) LookupName = nullptr;79decltype(&::pci_read_byte) PCIReadByte = nullptr;8081private:82void *mHandle = nullptr;83bool mValid = false;84};8586} // anonymous namespace8788// Adds an entry per PCI GPU found and fills the device and vendor ID.89bool GetPCIDevicesWithLibPCI(std::vector<GPUDeviceInfo> *devices)90{91LibPCI pci;92if (!pci.IsValid())93{94return false;95}9697pci_access *access = pci.Alloc();98ASSERT(access != nullptr);99pci.Init(access);100pci.ScanBus(access);101102for (pci_dev *device = access->devices; device != nullptr; device = device->next)103{104pci.FillInfo(device, PCI_FILL_IDENT | PCI_FILL_CLASS);105106// Skip non-GPU devices107if (device->device_class >> 8 != PCI_BASE_CLASS_DISPLAY)108{109continue;110}111112// Skip unknown devices113if (device->vendor_id == 0 || device->device_id == 0)114{115continue;116}117118GPUDeviceInfo info;119info.vendorId = device->vendor_id;120info.deviceId = device->device_id;121info.revisionId = pci.PCIReadByte(device, PCI_REVISION_ID);122123devices->push_back(info);124}125126pci.Cleanup(access);127128return true;129}130} // namespace angle131132133