Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/gpu_info_util/SystemInfo_libpci.cpp
1693 views
1
//
2
// Copyright 2013 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
7
// SystemInfo_libpci.cpp: implementation of the libPCI-specific parts of SystemInfo.h
8
9
#include "gpu_info_util/SystemInfo_internal.h"
10
11
#include <dlfcn.h>
12
#include <pci/pci.h>
13
#include <unistd.h>
14
15
#include "common/angleutils.h"
16
#include "common/debug.h"
17
18
#if !defined(GPU_INFO_USE_LIBPCI)
19
# error SystemInfo_libpci.cpp compiled without GPU_INFO_USE_LIBPCI
20
#endif
21
22
namespace angle
23
{
24
25
namespace
26
{
27
28
struct LibPCI : private angle::NonCopyable
29
{
30
LibPCI()
31
{
32
if (access("/sys/bus/pci/", F_OK) != 0 && access("/sys/bs/pci_express/", F_OK) != 0)
33
{
34
return;
35
}
36
37
mHandle = dlopen("libpci.so.3", RTLD_LAZY);
38
39
if (mHandle == nullptr)
40
{
41
mHandle = dlopen("libpci.so", RTLD_LAZY);
42
}
43
44
if (mHandle == nullptr)
45
{
46
return;
47
}
48
49
mValid =
50
(Alloc = reinterpret_cast<decltype(Alloc)>(dlsym(mHandle, "pci_alloc"))) != nullptr &&
51
(Init = reinterpret_cast<decltype(Init)>(dlsym(mHandle, "pci_init"))) != nullptr &&
52
(Cleanup = reinterpret_cast<decltype(Cleanup)>(dlsym(mHandle, "pci_cleanup"))) !=
53
nullptr &&
54
(ScanBus = reinterpret_cast<decltype(ScanBus)>(dlsym(mHandle, "pci_scan_bus"))) !=
55
nullptr &&
56
(FillInfo = reinterpret_cast<decltype(FillInfo)>(dlsym(mHandle, "pci_fill_info"))) !=
57
nullptr &&
58
(LookupName = reinterpret_cast<decltype(LookupName)>(
59
dlsym(mHandle, "pci_lookup_name"))) != nullptr &&
60
(PCIReadByte = reinterpret_cast<decltype(PCIReadByte)>(
61
dlsym(mHandle, "pci_read_byte"))) != nullptr;
62
}
63
64
bool IsValid() const { return mValid; }
65
66
~LibPCI()
67
{
68
if (mHandle != nullptr)
69
{
70
dlclose(mHandle);
71
}
72
}
73
74
decltype(&::pci_alloc) Alloc = nullptr;
75
decltype(&::pci_init) Init = nullptr;
76
decltype(&::pci_cleanup) Cleanup = nullptr;
77
decltype(&::pci_scan_bus) ScanBus = nullptr;
78
decltype(&::pci_fill_info) FillInfo = nullptr;
79
decltype(&::pci_lookup_name) LookupName = nullptr;
80
decltype(&::pci_read_byte) PCIReadByte = nullptr;
81
82
private:
83
void *mHandle = nullptr;
84
bool mValid = false;
85
};
86
87
} // anonymous namespace
88
89
// Adds an entry per PCI GPU found and fills the device and vendor ID.
90
bool GetPCIDevicesWithLibPCI(std::vector<GPUDeviceInfo> *devices)
91
{
92
LibPCI pci;
93
if (!pci.IsValid())
94
{
95
return false;
96
}
97
98
pci_access *access = pci.Alloc();
99
ASSERT(access != nullptr);
100
pci.Init(access);
101
pci.ScanBus(access);
102
103
for (pci_dev *device = access->devices; device != nullptr; device = device->next)
104
{
105
pci.FillInfo(device, PCI_FILL_IDENT | PCI_FILL_CLASS);
106
107
// Skip non-GPU devices
108
if (device->device_class >> 8 != PCI_BASE_CLASS_DISPLAY)
109
{
110
continue;
111
}
112
113
// Skip unknown devices
114
if (device->vendor_id == 0 || device->device_id == 0)
115
{
116
continue;
117
}
118
119
GPUDeviceInfo info;
120
info.vendorId = device->vendor_id;
121
info.deviceId = device->device_id;
122
info.revisionId = pci.PCIReadByte(device, PCI_REVISION_ID);
123
124
devices->push_back(info);
125
}
126
127
pci.Cleanup(access);
128
129
return true;
130
}
131
} // namespace angle
132
133