gpu-aux 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gpu_aux-1.2.0/API.md +273 -0
- gpu_aux-1.2.0/LICENSE +21 -0
- gpu_aux-1.2.0/MANIFEST.in +3 -0
- gpu_aux-1.2.0/PKG-INFO +119 -0
- gpu_aux-1.2.0/README.md +98 -0
- gpu_aux-1.2.0/gpu_aux/__init__.py +20 -0
- gpu_aux-1.2.0/gpu_aux/adl.py +370 -0
- gpu_aux-1.2.0/gpu_aux/api.py +240 -0
- gpu_aux-1.2.0/gpu_aux/intel.py +563 -0
- gpu_aux-1.2.0/gpu_aux/nvapi.py +316 -0
- gpu_aux-1.2.0/gpu_aux.egg-info/PKG-INFO +119 -0
- gpu_aux-1.2.0/gpu_aux.egg-info/SOURCES.txt +14 -0
- gpu_aux-1.2.0/gpu_aux.egg-info/dependency_links.txt +1 -0
- gpu_aux-1.2.0/gpu_aux.egg-info/top_level.txt +1 -0
- gpu_aux-1.2.0/pyproject.toml +41 -0
- gpu_aux-1.2.0/setup.cfg +4 -0
gpu_aux-1.2.0/API.md
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# gpu_aux API 说明
|
|
2
|
+
|
|
3
|
+
`gpu_aux` 是 Windows x64 下的纯 Python DisplayPort AUX 访问库。公共 API
|
|
4
|
+
集中从 `gpu_aux` 包导入,底层 AMD ADL、NVIDIA NVAPI、Intel IGCL 绑定属于实现细节。
|
|
5
|
+
|
|
6
|
+
## 导入
|
|
7
|
+
|
|
8
|
+
```python
|
|
9
|
+
from gpu_aux import (
|
|
10
|
+
AuxError,
|
|
11
|
+
AuxPort,
|
|
12
|
+
enumerate_gpus,
|
|
13
|
+
enumerate_gpus_and_ports,
|
|
14
|
+
enumerate_ports,
|
|
15
|
+
)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
支持的 `backend` 参数为:
|
|
19
|
+
|
|
20
|
+
| backend | 底层接口 | 运行依赖 |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| `"AMD"` | AMD ADL | 系统可加载 `atiadlxx.dll` 或 `atiadlxy.dll` |
|
|
23
|
+
| `"NVIDIA"` | NVIDIA NVAPI | 系统可加载 `nvapi64.dll` |
|
|
24
|
+
| `"INTEL"` | Intel IGCL | 系统可加载 Intel IGCL `ControlLib.dll` |
|
|
25
|
+
|
|
26
|
+
`backend` 大小写不敏感,会在内部归一化为 `"AMD"`、`"NVIDIA"` 或 `"INTEL"`。
|
|
27
|
+
|
|
28
|
+
## 快速示例
|
|
29
|
+
|
|
30
|
+
枚举 GPU 和端口:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from gpu_aux import enumerate_gpus, enumerate_ports
|
|
34
|
+
|
|
35
|
+
backend = "NVIDIA"
|
|
36
|
+
|
|
37
|
+
for gpu_index, gpu in enumerate(enumerate_gpus(backend)):
|
|
38
|
+
print(gpu_index, gpu.backend, gpu.name, gpu.display_name)
|
|
39
|
+
|
|
40
|
+
for port in enumerate_ports(backend, gpu_index):
|
|
41
|
+
print(port.kind, port.identity, port.name)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
读取第一个 NVIDIA DP 端口的 DPCD 头 16 字节:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from gpu_aux import AuxPort
|
|
48
|
+
|
|
49
|
+
with AuxPort("DP", index=0, gpu_index=0, backend="NVIDIA") as port:
|
|
50
|
+
data = port.read_dpcd(0x00000, 16)
|
|
51
|
+
print(data.hex(" ").upper())
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
读取 EDID:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from gpu_aux import AuxPort
|
|
58
|
+
|
|
59
|
+
with AuxPort("DP", index=0, gpu_index=0, backend="NVIDIA") as port:
|
|
60
|
+
edid = port.i2c_read(0x50, 0x00, 128)
|
|
61
|
+
print(edid[:8].hex(" ").upper())
|
|
62
|
+
print("checksum:", sum(edid) & 0xFF)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 枚举 API
|
|
66
|
+
|
|
67
|
+
### `enumerate_gpus(backend: str) -> list[Adapter]`
|
|
68
|
+
|
|
69
|
+
返回指定 backend 下的物理 GPU 列表,不需要创建 `AuxPort`。
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from gpu_aux import enumerate_gpus
|
|
73
|
+
|
|
74
|
+
for gpu in enumerate_gpus("AMD"):
|
|
75
|
+
print(gpu.index, gpu.name, gpu.bus, gpu.device, gpu.function)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
AMD backend 会按 PCI bus/device/function 合并 ADL 可能返回的重复逻辑 adapter。
|
|
79
|
+
|
|
80
|
+
### `enumerate_ports(backend: str, gpu_index: int = 0) -> list[Port]`
|
|
81
|
+
|
|
82
|
+
返回指定 GPU 上已连接的 DP/eDP AUX 端口列表。
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from gpu_aux import enumerate_ports
|
|
86
|
+
|
|
87
|
+
for port in enumerate_ports("INTEL", gpu_index=0):
|
|
88
|
+
print(port.kind, port.identity)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`gpu_index` 是 `enumerate_gpus(backend)` 返回列表中的序号。若索引不存在,
|
|
92
|
+
会抛出 `AuxError`。
|
|
93
|
+
|
|
94
|
+
### `enumerate_gpus_and_ports(backend: str) -> list[GpuPorts]`
|
|
95
|
+
|
|
96
|
+
一次返回 GPU 和端口快照。
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from gpu_aux import enumerate_gpus_and_ports
|
|
100
|
+
|
|
101
|
+
for item in enumerate_gpus_and_ports("NVIDIA"):
|
|
102
|
+
print(item.gpu_index, item.adapter.name)
|
|
103
|
+
for port in item.ports:
|
|
104
|
+
print(" ", port.kind, port.identity)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
返回项 `GpuPorts` 包含:
|
|
108
|
+
|
|
109
|
+
| 字段 | 类型 | 说明 |
|
|
110
|
+
| --- | --- | --- |
|
|
111
|
+
| `gpu_index` | `int` | GPU 在该 backend 下的序号 |
|
|
112
|
+
| `adapter` | `Adapter` | GPU 信息 |
|
|
113
|
+
| `ports` | `tuple[Port, ...]` | 该 GPU 上的已连接 DP/eDP 端口快照 |
|
|
114
|
+
|
|
115
|
+
## `AuxPort`
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
AuxPort(kind: str, index: int = 0, gpu_index: int = 0, *, backend: str)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
打开一个 DP/eDP AUX 端点。推荐用 `with` 管理生命周期:
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from gpu_aux import AuxPort
|
|
125
|
+
|
|
126
|
+
with AuxPort("eDP", index=0, gpu_index=0, backend="AMD") as port:
|
|
127
|
+
print(port.identity)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
参数:
|
|
131
|
+
|
|
132
|
+
| 参数 | 说明 |
|
|
133
|
+
| --- | --- |
|
|
134
|
+
| `kind` | 端口类型,支持 `"DP"` 或 `"eDP"`,大小写不敏感 |
|
|
135
|
+
| `index` | 同一 GPU、同一 `kind` 下的端口序号,从 `0` 开始 |
|
|
136
|
+
| `gpu_index` | 同一 backend 下的 GPU 序号,从 `0` 开始 |
|
|
137
|
+
| `backend` | 必填关键字参数,支持 `"AMD"`、`"NVIDIA"`、`"INTEL"` |
|
|
138
|
+
|
|
139
|
+
例如,同一 NVIDIA GPU 上第二个外接 DP 端口:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
AuxPort("DP", index=1, gpu_index=0, backend="NVIDIA")
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
多个同 backend 的 `AuxPort` 会共享同一个底层 context,并通过引用计数在最后一个
|
|
146
|
+
对象关闭时释放。显式调用 `close()` 后,继续使用该对象会抛出 `AuxError`。
|
|
147
|
+
|
|
148
|
+
### 属性
|
|
149
|
+
|
|
150
|
+
| 属性 | 类型 | 说明 |
|
|
151
|
+
| --- | --- | --- |
|
|
152
|
+
| `info` | `Port` | 当前端口信息 |
|
|
153
|
+
| `identity` | `str` | backend 内唯一端口标识 |
|
|
154
|
+
| `kind` | `str` | `"DP"` 或 `"eDP"` |
|
|
155
|
+
| `gpu_index` | `int` | GPU 序号 |
|
|
156
|
+
| `backend` | `str` | `"AMD"`、`"NVIDIA"` 或 `"INTEL"` |
|
|
157
|
+
| `index` | `int` | 同 GPU、同端口类型下的端口序号 |
|
|
158
|
+
|
|
159
|
+
## DPCD 方法
|
|
160
|
+
|
|
161
|
+
### `read_dpcd(address: int, length: int) -> bytes`
|
|
162
|
+
|
|
163
|
+
读取 DPCD 数据。`address` 范围为 `0x00000..0xFFFFF`,`length` 必须大于 `0`。
|
|
164
|
+
库会按底层接口限制自动分块,当前各 backend 单次 Native AUX 分块最大 16 字节。
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
with AuxPort("DP", 0, 0, backend="NVIDIA") as port:
|
|
168
|
+
dpcd = port.read_dpcd(0x00000, 16)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### `write_dpcd(address: int, data: bytes) -> None`
|
|
172
|
+
|
|
173
|
+
写入 DPCD 数据。`data` 不能为空。写操作会改变硬件状态,建议先读取原值,并在
|
|
174
|
+
`finally` 中恢复。
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
with AuxPort("DP", 0, 0, backend="AMD") as port:
|
|
178
|
+
address = 0x00102
|
|
179
|
+
old = port.read_dpcd(address, 1)
|
|
180
|
+
try:
|
|
181
|
+
port.write_dpcd(address, bytes([0xC0]))
|
|
182
|
+
finally:
|
|
183
|
+
port.write_dpcd(address, old)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## I2C-over-AUX 方法
|
|
187
|
+
|
|
188
|
+
公共 I2C 参数使用 7-bit device address,例如 EDID 数据地址 `0x50`、EDID segment
|
|
189
|
+
pointer 地址 `0x30`。为兼容部分调用方式,传入 8-bit address 时会归一化为 7-bit。
|
|
190
|
+
|
|
191
|
+
### `i2c_read(device: int, register: int, length: int) -> bytes`
|
|
192
|
+
|
|
193
|
+
从 I2C 设备读取寄存器数据。`device` 必须可放入一个字节,`register` 范围为
|
|
194
|
+
`0x00..0xFF`,`length` 必须大于 `0`。
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
with AuxPort("DP", 0, 0, backend="INTEL") as port:
|
|
198
|
+
edid = port.i2c_read(0x50, 0x00, 128)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### `i2c_write(device: int, register: int, data: bytes) -> None`
|
|
202
|
+
|
|
203
|
+
向 I2C 设备写入寄存器数据。`data` 不能为空。对 EDID segment pointer `0x30`
|
|
204
|
+
的写入只允许 1 字节。
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
with AuxPort("DP", 0, 0, backend="NVIDIA") as port:
|
|
208
|
+
port.i2c_write(0x30, 0x00, bytes([0x00]))
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## 数据类
|
|
212
|
+
|
|
213
|
+
### `Adapter`
|
|
214
|
+
|
|
215
|
+
`Adapter` 表示一个物理 GPU。
|
|
216
|
+
|
|
217
|
+
| 字段 | 类型 | 说明 |
|
|
218
|
+
| --- | --- | --- |
|
|
219
|
+
| `index` | `int` | backend 内 GPU 序号或底层 adapter index |
|
|
220
|
+
| `name` | `str` | GPU 名称 |
|
|
221
|
+
| `display_name` | `str` | 显示名称 |
|
|
222
|
+
| `bus` | `int` | PCI bus |
|
|
223
|
+
| `device` | `int` | PCI device |
|
|
224
|
+
| `function` | `int` | PCI function |
|
|
225
|
+
| `backend` | `str` | `"AMD"`、`"NVIDIA"` 或 `"INTEL"` |
|
|
226
|
+
|
|
227
|
+
### `Port`
|
|
228
|
+
|
|
229
|
+
`Port` 表示一个已连接的 DP/eDP AUX 目标。
|
|
230
|
+
|
|
231
|
+
| 字段/属性 | 类型 | 说明 |
|
|
232
|
+
| --- | --- | --- |
|
|
233
|
+
| `adapter` | `Adapter` | 所属 GPU |
|
|
234
|
+
| `index` | `int` | backend 枚举结果中的端口位置 |
|
|
235
|
+
| `logical_display_index` | `int` | backend 用于访问该端口的逻辑 ID |
|
|
236
|
+
| `physical_display_index` | `int` | backend 暴露的物理/Windows 显示 ID |
|
|
237
|
+
| `name` | `str` | 显示目标名称 |
|
|
238
|
+
| `manufacturer` | `str` | 厂商名,部分 backend 可能为空 |
|
|
239
|
+
| `display_type` | `int` | backend 显示类型值 |
|
|
240
|
+
| `output_type` | `int` | backend 输出类型值 |
|
|
241
|
+
| `connector` | `int` | backend connector 值 |
|
|
242
|
+
| `connected` | `bool` | 是否连接 |
|
|
243
|
+
| `backend` | `str` | 底层 backend 标记,例如 `adl`、`nvapi`、`igcl` |
|
|
244
|
+
| `identity` | `str` | 端口身份字符串 |
|
|
245
|
+
| `kind` | `str` | `"DP"` 或 `"eDP"` |
|
|
246
|
+
|
|
247
|
+
`identity` 可用于日志和问题定位,但不要把它当成跨驱动版本永久稳定的硬件序列号。
|
|
248
|
+
|
|
249
|
+
## 异常
|
|
250
|
+
|
|
251
|
+
### `AuxError`
|
|
252
|
+
|
|
253
|
+
底层库加载、backend 初始化、GPU/端口不存在、AUX 交易失败等运行时错误会抛出
|
|
254
|
+
`AuxError`。
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
from gpu_aux import AuxError, enumerate_gpus
|
|
258
|
+
|
|
259
|
+
try:
|
|
260
|
+
print(enumerate_gpus("NVIDIA"))
|
|
261
|
+
except AuxError as error:
|
|
262
|
+
print("NVIDIA backend unavailable:", error)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
参数类型或范围错误通常抛出 `TypeError` 或 `ValueError`。
|
|
266
|
+
|
|
267
|
+
## 安全建议
|
|
268
|
+
|
|
269
|
+
- 默认优先使用 `enumerate_gpus()`、`enumerate_ports()` 和 `read_dpcd()` 做只读检查。
|
|
270
|
+
- 不要对未知 DPCD 地址做探索性写入。
|
|
271
|
+
- 写入前先读取原值,并在 `finally` 中恢复。
|
|
272
|
+
- 单个端口失败时记录 `backend`、`gpu_index`、`port.identity`、地址和错误信息。
|
|
273
|
+
- HDMI 不是 AUX 目标,本库只枚举 DP/eDP 端口。
|
gpu_aux-1.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 cnbright
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
gpu_aux-1.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gpu-aux
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: Direct Python bindings for AMD, NVIDIA, and Intel DisplayPort AUX access
|
|
5
|
+
Author: cnbright
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cnbright/amd-aux
|
|
8
|
+
Project-URL: Repository, https://github.com/cnbright/amd-aux
|
|
9
|
+
Project-URL: Issues, https://github.com/cnbright/amd-aux/issues
|
|
10
|
+
Keywords: amd,aux,displayport,dpcd,edid,gpu,intel,nvidia
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Topic :: System :: Hardware
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
|
|
22
|
+
# gpu_aux
|
|
23
|
+
|
|
24
|
+
Windows x64 纯 Python GPU AUX 包。Python 使用 `ctypes` 直接加载系统 AMD
|
|
25
|
+
`atiadlxx.dll`、NVIDIA `nvapi64.dll` 或 Intel IGCL `ControlLib.dll`,不包含或依赖
|
|
26
|
+
C/C++ 中间 DLL
|
|
27
|
+
|
|
28
|
+
完整接口说明见 [API.md](./API.md)。
|
|
29
|
+
|
|
30
|
+
## 安装
|
|
31
|
+
|
|
32
|
+
通过 PyPI 安装:
|
|
33
|
+
|
|
34
|
+
```powershell
|
|
35
|
+
python -m pip install gpu-aux
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
从本地源码目录安装:
|
|
39
|
+
|
|
40
|
+
```powershell
|
|
41
|
+
python -m pip install .
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
支持:
|
|
45
|
+
|
|
46
|
+
- 按 PCI 地址合并 ADL 重复项,枚举物理 AMD GPU 和每个已连接 DP/eDP 端口
|
|
47
|
+
- 枚举 NVIDIA 物理 GPU 和已连接 DP 端口
|
|
48
|
+
- 枚举 Intel IGCL GPU 和已连接 DP/eDP 端口
|
|
49
|
+
- AMD DPCD 读写:`ADL_Display_NativeAUXChannel_Access`
|
|
50
|
+
- AMD I2C-over-AUX 读写:`ADL_Display_DDCBlockAccess_Get`
|
|
51
|
+
- NVIDIA DPCD/I2C-over-AUX 读写:`NvAPI_Disp_DpAuxChannelControl`
|
|
52
|
+
- Intel DPCD/I2C-over-AUX 读写:`ctlAUXAccess`
|
|
53
|
+
- 以 backend、GPU index 和显示目标 ID 区分多个 DP/eDP 端口
|
|
54
|
+
|
|
55
|
+
公开 GPU API 参考:
|
|
56
|
+
|
|
57
|
+
- AMD ADL SDK:[AMD Display Library](https://gpuopen-librariesandsdks.github.io/adl/);
|
|
58
|
+
DDC/I2C 入口见 [I2C, DDC and EDID APIs](https://gpuopen-librariesandsdks.github.io/adl/group__I2CDDCEDIDAPI.html)。
|
|
59
|
+
- Intel IGCL:[Programming Guide](https://intel.github.io/drivers.gpu.control-library/prog.html)
|
|
60
|
+
和 [Control API](https://intel.github.io/drivers.gpu.control-library/Control/api.html)。
|
|
61
|
+
- NVIDIA NVAPI:[NVAPI Reference Documentation](https://docs.nvidia.com/nvapi/documentation.html)。
|
|
62
|
+
本项目使用的 DP AUX 入口不在公开 `nvapi.h` 中声明,属于逆向确认的私有接口。
|
|
63
|
+
|
|
64
|
+
直接构造一个端口对象:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from gpu_aux import AuxPort
|
|
68
|
+
|
|
69
|
+
with AuxPort("DP", index=0, gpu_index=0, backend="NVIDIA") as dp:
|
|
70
|
+
print(dp.read_dpcd(0x00000, 16).hex(" "))
|
|
71
|
+
edid = dp.i2c_read(0x50, 0, 128)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
GPU 与端口枚举是两个独立的模块级函数,不需要先创建 `AuxPort`:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from gpu_aux import enumerate_gpus, enumerate_ports
|
|
78
|
+
|
|
79
|
+
for gpu_index, gpu in enumerate(enumerate_gpus("NVIDIA")):
|
|
80
|
+
print(gpu_index, gpu.backend, gpu.name)
|
|
81
|
+
for port in enumerate_ports("NVIDIA", gpu_index):
|
|
82
|
+
print(port.kind, port.identity, port.name)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`index` 是同一 GPU、同一端口类型内的序号,例如第二个外接 DP 使用`AuxPort("DP", index=1, gpu_index=0, backend="NVIDIA")`。
|
|
86
|
+
|
|
87
|
+
多个同后端 `AuxPort`对象共享同一 context,并在最后一个对象关闭时释放。后端必须由调用方显式指定,不会自动选择。
|
|
88
|
+
|
|
89
|
+
## 测试
|
|
90
|
+
|
|
91
|
+
从项目根目录运行只读测试:
|
|
92
|
+
|
|
93
|
+
```powershell
|
|
94
|
+
python .\tests\smoke_test.py NVIDIA
|
|
95
|
+
python .\tests\smoke_test.py INTEL
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
读写硬件测试会向 DPCD `0x00102` 写入 `C0`、回读并恢复原值,同时通过
|
|
99
|
+
I2C 地址 `0x30/0x50` 读取 EDID:
|
|
100
|
+
|
|
101
|
+
```powershell
|
|
102
|
+
python .\tests\hardware_aux_test_nvidia.py
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
AMD 写测试使用独立入口:
|
|
106
|
+
|
|
107
|
+
```powershell
|
|
108
|
+
python .\tests\hardware_aux_test_amd.py
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Intel 写测试也使用独立入口:
|
|
112
|
+
|
|
113
|
+
```powershell
|
|
114
|
+
python .\tests\hardware_aux_test_intel.py
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
私有 ADL/NVAPI AUX 接口可能随显卡驱动变化;Intel 路径使用公开 IGCL
|
|
118
|
+
`ctlAUXAccess`。当前实现要求 Windows x64、64 位 Python、AMD/NVIDIA/Intel
|
|
119
|
+
DP/eDP 链路;包内会串行化 AUX 事务。
|
gpu_aux-1.2.0/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# gpu_aux
|
|
2
|
+
|
|
3
|
+
Windows x64 纯 Python GPU AUX 包。Python 使用 `ctypes` 直接加载系统 AMD
|
|
4
|
+
`atiadlxx.dll`、NVIDIA `nvapi64.dll` 或 Intel IGCL `ControlLib.dll`,不包含或依赖
|
|
5
|
+
C/C++ 中间 DLL
|
|
6
|
+
|
|
7
|
+
完整接口说明见 [API.md](./API.md)。
|
|
8
|
+
|
|
9
|
+
## 安装
|
|
10
|
+
|
|
11
|
+
通过 PyPI 安装:
|
|
12
|
+
|
|
13
|
+
```powershell
|
|
14
|
+
python -m pip install gpu-aux
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
从本地源码目录安装:
|
|
18
|
+
|
|
19
|
+
```powershell
|
|
20
|
+
python -m pip install .
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
支持:
|
|
24
|
+
|
|
25
|
+
- 按 PCI 地址合并 ADL 重复项,枚举物理 AMD GPU 和每个已连接 DP/eDP 端口
|
|
26
|
+
- 枚举 NVIDIA 物理 GPU 和已连接 DP 端口
|
|
27
|
+
- 枚举 Intel IGCL GPU 和已连接 DP/eDP 端口
|
|
28
|
+
- AMD DPCD 读写:`ADL_Display_NativeAUXChannel_Access`
|
|
29
|
+
- AMD I2C-over-AUX 读写:`ADL_Display_DDCBlockAccess_Get`
|
|
30
|
+
- NVIDIA DPCD/I2C-over-AUX 读写:`NvAPI_Disp_DpAuxChannelControl`
|
|
31
|
+
- Intel DPCD/I2C-over-AUX 读写:`ctlAUXAccess`
|
|
32
|
+
- 以 backend、GPU index 和显示目标 ID 区分多个 DP/eDP 端口
|
|
33
|
+
|
|
34
|
+
公开 GPU API 参考:
|
|
35
|
+
|
|
36
|
+
- AMD ADL SDK:[AMD Display Library](https://gpuopen-librariesandsdks.github.io/adl/);
|
|
37
|
+
DDC/I2C 入口见 [I2C, DDC and EDID APIs](https://gpuopen-librariesandsdks.github.io/adl/group__I2CDDCEDIDAPI.html)。
|
|
38
|
+
- Intel IGCL:[Programming Guide](https://intel.github.io/drivers.gpu.control-library/prog.html)
|
|
39
|
+
和 [Control API](https://intel.github.io/drivers.gpu.control-library/Control/api.html)。
|
|
40
|
+
- NVIDIA NVAPI:[NVAPI Reference Documentation](https://docs.nvidia.com/nvapi/documentation.html)。
|
|
41
|
+
本项目使用的 DP AUX 入口不在公开 `nvapi.h` 中声明,属于逆向确认的私有接口。
|
|
42
|
+
|
|
43
|
+
直接构造一个端口对象:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from gpu_aux import AuxPort
|
|
47
|
+
|
|
48
|
+
with AuxPort("DP", index=0, gpu_index=0, backend="NVIDIA") as dp:
|
|
49
|
+
print(dp.read_dpcd(0x00000, 16).hex(" "))
|
|
50
|
+
edid = dp.i2c_read(0x50, 0, 128)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
GPU 与端口枚举是两个独立的模块级函数,不需要先创建 `AuxPort`:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from gpu_aux import enumerate_gpus, enumerate_ports
|
|
57
|
+
|
|
58
|
+
for gpu_index, gpu in enumerate(enumerate_gpus("NVIDIA")):
|
|
59
|
+
print(gpu_index, gpu.backend, gpu.name)
|
|
60
|
+
for port in enumerate_ports("NVIDIA", gpu_index):
|
|
61
|
+
print(port.kind, port.identity, port.name)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`index` 是同一 GPU、同一端口类型内的序号,例如第二个外接 DP 使用`AuxPort("DP", index=1, gpu_index=0, backend="NVIDIA")`。
|
|
65
|
+
|
|
66
|
+
多个同后端 `AuxPort`对象共享同一 context,并在最后一个对象关闭时释放。后端必须由调用方显式指定,不会自动选择。
|
|
67
|
+
|
|
68
|
+
## 测试
|
|
69
|
+
|
|
70
|
+
从项目根目录运行只读测试:
|
|
71
|
+
|
|
72
|
+
```powershell
|
|
73
|
+
python .\tests\smoke_test.py NVIDIA
|
|
74
|
+
python .\tests\smoke_test.py INTEL
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
读写硬件测试会向 DPCD `0x00102` 写入 `C0`、回读并恢复原值,同时通过
|
|
78
|
+
I2C 地址 `0x30/0x50` 读取 EDID:
|
|
79
|
+
|
|
80
|
+
```powershell
|
|
81
|
+
python .\tests\hardware_aux_test_nvidia.py
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
AMD 写测试使用独立入口:
|
|
85
|
+
|
|
86
|
+
```powershell
|
|
87
|
+
python .\tests\hardware_aux_test_amd.py
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Intel 写测试也使用独立入口:
|
|
91
|
+
|
|
92
|
+
```powershell
|
|
93
|
+
python .\tests\hardware_aux_test_intel.py
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
私有 ADL/NVAPI AUX 接口可能随显卡驱动变化;Intel 路径使用公开 IGCL
|
|
97
|
+
`ctlAUXAccess`。当前实现要求 Windows x64、64 位 Python、AMD/NVIDIA/Intel
|
|
98
|
+
DP/eDP 链路;包内会串行化 AUX 事务。
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Direct Python access to DisplayPort AUX functions."""
|
|
2
|
+
|
|
3
|
+
from .adl import Adapter, AmdAux, AuxError, Port
|
|
4
|
+
from .api import AuxPort, GpuPorts, enumerate_gpus, enumerate_gpus_and_ports, enumerate_ports
|
|
5
|
+
from .intel import IntelAux
|
|
6
|
+
from .nvapi import NvidiaAux
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"Adapter",
|
|
10
|
+
"AmdAux",
|
|
11
|
+
"AuxError",
|
|
12
|
+
"AuxPort",
|
|
13
|
+
"GpuPorts",
|
|
14
|
+
"IntelAux",
|
|
15
|
+
"NvidiaAux",
|
|
16
|
+
"Port",
|
|
17
|
+
"enumerate_gpus",
|
|
18
|
+
"enumerate_gpus_and_ports",
|
|
19
|
+
"enumerate_ports",
|
|
20
|
+
]
|