diff options
author | Tobias Hunger <tobias.hunger@qt.io> | 2019-04-16 16:32:08 +0200 |
---|---|---|
committer | Tobias Hunger <tobias.hunger@qt.io> | 2019-04-16 16:32:08 +0200 |
commit | 6630937e63ae5797487b86743a7733c8ae5cc42c (patch) | |
tree | 3d53dacf6430f9099e1fb20835881205de674961 /src/3rdparty/angle/src/gpu_info_util/SystemInfo_libpci.cpp | |
parent | 37ed6dae00640f9cc980ffda05347c12a7eb5d7e (diff) | |
parent | c7af193d2e49e9f10b86262e63d8d13abf72b5cf (diff) |
Merge commit 'dev' into 'wip/cmake-merge'
Change-Id: I176c40d031be26a1dd1cf08843e448a660598783
Diffstat (limited to 'src/3rdparty/angle/src/gpu_info_util/SystemInfo_libpci.cpp')
-rw-r--r-- | src/3rdparty/angle/src/gpu_info_util/SystemInfo_libpci.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/3rdparty/angle/src/gpu_info_util/SystemInfo_libpci.cpp b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_libpci.cpp new file mode 100644 index 0000000000..07c72872ad --- /dev/null +++ b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_libpci.cpp @@ -0,0 +1,132 @@ +// +// Copyright (c) 2013-2017 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_libpci.cpp: implementation of the libPCI-specific parts of SystemInfo.h + +#include "gpu_info_util/SystemInfo_internal.h" + +#include <dlfcn.h> +#include <pci/pci.h> +#include <unistd.h> + +#include "common/angleutils.h" +#include "common/debug.h" + +#if !defined(GPU_INFO_USE_LIBPCI) +#error SystemInfo_libpci.cpp compiled without GPU_INFO_USE_LIBPCI +#endif + +namespace angle +{ + +namespace +{ + +struct LibPCI : private angle::NonCopyable +{ + LibPCI() + { + if (access("/sys/bus/pci/", F_OK) != 0 && access("/sys/bs/pci_express/", F_OK) != 0) + { + return; + } + + mHandle = dlopen("libpci.so.3", RTLD_LAZY); + + if (mHandle == nullptr) + { + mHandle = dlopen("libpci.so", RTLD_LAZY); + } + + if (mHandle == nullptr) + { + return; + } + + mValid = + (Alloc = reinterpret_cast<decltype(Alloc)>(dlsym(mHandle, "pci_alloc"))) != nullptr && + (Init = reinterpret_cast<decltype(Init)>(dlsym(mHandle, "pci_init"))) != nullptr && + (Cleanup = reinterpret_cast<decltype(Cleanup)>(dlsym(mHandle, "pci_cleanup"))) != + nullptr && + (ScanBus = reinterpret_cast<decltype(ScanBus)>(dlsym(mHandle, "pci_scan_bus"))) != + nullptr && + (FillInfo = reinterpret_cast<decltype(FillInfo)>(dlsym(mHandle, "pci_fill_info"))) != + nullptr && + (LookupName = reinterpret_cast<decltype(LookupName)>( + dlsym(mHandle, "pci_lookup_name"))) != nullptr; + } + + bool IsValid() const { return mValid; } + + ~LibPCI() + { + if (mHandle != nullptr) + { + dlclose(mHandle); + } + } + + decltype(&::pci_alloc) Alloc = nullptr; + decltype(&::pci_init) Init = nullptr; + decltype(&::pci_cleanup) Cleanup = nullptr; + decltype(&::pci_scan_bus) ScanBus = nullptr; + decltype(&::pci_fill_info) FillInfo = nullptr; + decltype(&::pci_lookup_name) LookupName = nullptr; + + private: + void *mHandle = nullptr; + bool mValid = false; +}; + +} // anonymous namespace + +// Adds an entry per PCI GPU found and fills the device and vendor ID. +bool GetPCIDevicesWithLibPCI(std::vector<GPUDeviceInfo> *devices) +{ + LibPCI pci; + if (!pci.IsValid()) + { + return false; + } + + pci_access *access = pci.Alloc(); + ASSERT(access != nullptr); + pci.Init(access); + pci.ScanBus(access); + + for (pci_dev *device = access->devices; device != nullptr; device = device->next) + { + pci.FillInfo(device, PCI_FILL_IDENT | PCI_FILL_CLASS); + + // Skip non-GPU devices + switch (device->device_class) + { + case PCI_CLASS_DISPLAY_VGA: + case PCI_CLASS_DISPLAY_XGA: + case PCI_CLASS_DISPLAY_3D: + break; + default: + continue; + } + + // Skip unknown devices + if (device->vendor_id == 0 || device->device_id == 0) + { + continue; + } + + GPUDeviceInfo info; + info.vendorId = device->vendor_id; + info.deviceId = device->device_id; + + devices->push_back(info); + } + + pci.Cleanup(access); + + return true; +} +} |