c++ - 从 ioctl 调用 DRM_IOCTL_MODE_GETRESOURCES 返回零连接器计数
问题描述
我的目标是弄清楚如何进行快速屏幕捕获。一种方法是利用 GPU 抓取帧(然后在 GPU 上快速对其进行编码)。
我正在尝试在 Linux 上执行此操作,并使用 DRM/KMS 等低级 API 来实现此目的。
目前,我没有取回任何连接器。
跑步:Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-1044-aws x86_64)
C++ 代码:
#include <stdio.h>
#include <fcntl.h>
#include <drm/drm.h>
#include <drm/drm_mode.h>
#include <sys/ioctl.h>
#include <cstdint>
#include <stdint.h>
using namespace std;
int main() {
int dri_fd = open("/dev/dri/card0", O_RDWR);
printf("fd: %d\n", dri_fd);
if (dri_fd == -1) {
printf("Could not open card0\n");
return -1;
}
ioctl(dri_fd, DRM_IOCTL_SET_MASTER, 0); // We only need to be "master" to do the actual KMS mode setting
drm_mode_card_res res = {0};
ioctl(dri_fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
printf("FB Count: %d\n", res.count_fbs);
printf("Connector Count: %d\n", res.count_connectors);
printf("CRTC Count: %d\n", res.count_crtcs);
printf("Encoder Count: %d\n", res.count_encoders);
uint64_t fb_buf[10] = {0};
uint64_t crtc_buf[10] = {0};
uint64_t conn_buf[10] = {0};
uint64_t enc_buf[10] = {0};
res.fb_id_ptr = (uint64_t)fb_buf; // Frame buffer
res.crtc_id_ptr = (uint64_t)crtc_buf; // A CRTC represents the overall display pipeline.
res.connector_id_ptr = (uint64_t)conn_buf; // In DRM connectors are the general abstraction for display sinks, and include als fixed panels or anything else that can display pixels in some form.
res.encoder_id_ptr = (uint64_t)enc_buf; // An encoder takes pixel data from a CRTC and converts it to a format suitable for any attached connector.
// Get resource IDs
ioctl(dri_fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
return 0;
}
输出:
:~$ sudo ./capture
fd: 3
FB Count: 0
Connector Count: 0
CRTC Count: 0
Encoder Count: 0
我的期望是连接器计数或 FB 计数将返回非零值,因为我的 M60 NVIDIA GPU 似乎连接到 X11/Gnome:
ubuntu:~$ nvidia-smi
Fri Aug 2 00:59:01 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 430.30 Driver Version: 430.30 CUDA Version: 10.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 Tesla M60 Off | 00000000:00:1E.0 Off | 0 |
| N/A 28C P8 14W / 150W | 141MiB / 7618MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 3255 G /usr/lib/xorg/Xorg 57MiB |
| 0 3286 G /usr/bin/gnome-shell 82MiB |
+-----------------------------------------------------------------------------+
其他相关诊断信息:
ubuntu:~$ cat /etc/modprobe.d/nvidia.conf
options nvidia-drm modeset=1
ubuntu:~$ cat /etc/modprobe.d/blacklist.conf
# This file lists those modules which we don't want to be loaded by
# alias expansion, usually so some other driver will be loaded for the
# device instead.
# evbug is a debug tool that should be loaded explicitly
blacklist evbug
# these drivers are very simple, the HID drivers are usually preferred
blacklist usbmouse
blacklist usbkbd
# replaced by e100
blacklist eepro100
# replaced by tulip
blacklist de4x5
# causes no end of confusion by creating unexpected network interfaces
blacklist eth1394
# snd_intel8x0m can interfere with snd_intel8x0, doesn't seem to support much
# hardware on its own (Ubuntu bug #2011, #6810)
blacklist snd_intel8x0m
# Conflicts with dvb driver (which is better for handling this device)
blacklist snd_aw2
# Causes trackpads to stop working on Lenovo 11e 2nd gen (Ubuntu: #1802135)
# and Lenovo x240 to hang on boot (Ubuntu: #1802689)
blacklist i2c_i801
# replaced by p54pci
blacklist prism54
# replaced by b43 and ssb.
blacklist bcm43xx
# most apps now use garmin usb driver directly (Ubuntu: #114565)
blacklist garmin_gps
# replaced by asus-laptop (Ubuntu: #184721)
blacklist asus_acpi
# low-quality, just noise when being used for sound playback, causes
# hangs at desktop session start (Ubuntu: #246969)
blacklist snd_pcsp
# ugly and loud noise, getting on everyone's nerves; this should be done by a
# nice pulseaudio bing (Ubuntu: #77010)
blacklist pcspkr
# EDAC driver for amd76x clashes with the agp driver preventing the aperture
# from being initialised (Ubuntu: #297750). Blacklist so that the driver
# continues to build and is installable for the few cases where its
# really needed.
blacklist amd76x_edac
blacklist vga16fb
blacklist nouveau
blacklist rivafb
blacklist nvidiafb
blacklist rivatv
ubuntu:~$ lsmod
Module Size Used by
nvidia_drm 45056 3
nvidia_modeset 1110016 3 nvidia_drm
nvidia 18796544 218 nvidia_modeset
drm_kms_helper 167936 1 nvidia_drm
drm 393216 6 drm_kms_helper,nvidia_drm
i2c_core 73728 3 drm_kms_helper,nvidia,drm
fb_sys_fops 16384 1 drm_kms_helper
syscopyarea 16384 1 drm_kms_helper
sysfillrect 16384 1 drm_kms_helper
sysimgblt 16384 1 drm_kms_helper
ipmi_devintf 20480 0
ipmi_msghandler 53248 2 ipmi_devintf,nvidia
serio_raw 16384 0
sch_fq_codel 20480 9
ib_iser 49152 0
rdma_cm 61440 1 ib_iser
iw_cm 45056 1 rdma_cm
ib_cm 53248 1 rdma_cm
ib_core 225280 4 rdma_cm,iw_cm,ib_iser,ib_cm
iscsi_tcp 20480 0
libiscsi_tcp 20480 1 iscsi_tcp
libiscsi 53248 3 libiscsi_tcp,iscsi_tcp,ib_iser
scsi_transport_iscsi 98304 3 iscsi_tcp,ib_iser,libiscsi
parport_pc 36864 0
ppdev 20480 0
lp 20480 0
parport 49152 3 parport_pc,lp,ppdev
ip_tables 28672 0
x_tables 40960 1 ip_tables
autofs4 40960 2
btrfs 1126400 0
zstd_compress 163840 1 btrfs
raid10 53248 0
raid456 143360 0
async_raid6_recov 20480 1 raid456
async_memcpy 16384 2 raid456,async_raid6_recov
async_pq 16384 2 raid456,async_raid6_recov
async_xor 16384 3 async_pq,raid456,async_raid6_recov
async_tx 16384 5 async_pq,async_memcpy,async_xor,raid456,async_raid6_recov
xor 24576 2 async_xor,btrfs
raid6_pq 114688 4 async_pq,btrfs,raid456,async_raid6_recov
libcrc32c 16384 1 raid456
raid1 40960 0
raid0 20480 0
multipath 16384 0
linear 16384 0
crct10dif_pclmul 16384 0
crc32_pclmul 16384 0
ghash_clmulni_intel 16384 0
pcbc 16384 0
aesni_intel 188416 0
aes_x86_64 20480 1 aesni_intel
crypto_simd 16384 1 aesni_intel
glue_helper 16384 1 aesni_intel
cryptd 24576 3 crypto_simd,ghash_clmulni_intel,aesni_intel
ena 94208 0
ubuntu:~$ dmesg | grep -i NV
[ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.15.0-1044-aws root=UUID=8abb4f2d-c7e0-4daf-80b5-24e1c814cf55 ro rdblacklist=nouveau console=tty1 console=ttyS0 nvme_core.io_timeout=4294967295
[ 0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-4.15.0-1044-aws root=UUID=8abb4f2d-c7e0-4daf-80b5-24e1c814cf55 ro rdblacklist=nouveau console=tty1 console=ttyS0 nvme_core.io_timeout=4294967295
[ 0.616004] ACPI: Added _OSI(Linux-Lenovo-NV-HDMI-Audio)
[ 2.324353] rtc_cmos 00:02: alarms up to one day, 114 bytes nvram, hpet irqs
[ 7.467294] nvidia: loading out-of-tree module taints kernel.
[ 7.467301] nvidia: module license 'NVIDIA' taints kernel.
[ 7.476833] nvidia: module verification failed: signature and/or required key missing - tainting kernel
[ 7.488128] nvidia-nvlink: Nvlink Core is being initialized, major device number 243
[ 7.489962] nvidia 0000:00:1e.0: vgaarb: changed VGA decodes: olddecodes=io+mem,decodes=none:owns=io+mem
[ 7.490503] NVRM: loading NVIDIA UNIX x86_64 Kernel Module 430.30 Mon Jun 10 05:04:34 CDT 2019
[ 7.511462] nvidia-modeset: Loading NVIDIA Kernel Mode Setting Driver for UNIX platforms 430.30 Mon Jun 10 04:38:05 CDT 2019
[ 7.514021] [drm] [nvidia-drm] [GPU ID 0x0000001e] Loading driver
[ 8.790628] [drm] Initialized nvidia-drm 0.0.0 20160202 for 0000:00:1e.0 on minor 0
[ 227.400569] [drm] [nvidia-drm] [GPU ID 0x0000001e] Unloading driver
[ 227.400786] NVRM: Persistence mode is deprecated and will be removed in a future release. Please use nvidia-persistenced instead.
[ 227.585668] nvidia-modeset: Unloading
[ 227.876830] nvidia-nvlink: Unregistered the Nvlink Core, major device number 243
[ 237.950918] nvidia-nvlink: Nvlink Core is being initialized, major device number 243
[ 237.952092] nvidia 0000:00:1e.0: vgaarb: changed VGA decodes: olddecodes=none,decodes=none:owns=io+mem
[ 237.952418] NVRM: loading NVIDIA UNIX x86_64 Kernel Module 430.30 Mon Jun 10 05:04:34 CDT 2019
[ 237.955126] nvidia-modeset: Loading NVIDIA Kernel Mode Setting Driver for UNIX platforms 430.30 Mon Jun 10 04:38:05 CDT 2019
[ 237.956384] [drm] [nvidia-drm] [GPU ID 0x0000001e] Loading driver
[ 239.061266] [drm] Initialized nvidia-drm 0.0.0 20160202 for 0000:00:1e.0 on minor 0
解决方案
推荐阅读
- firebase - 在颤振中通过字符串获取数据
- c++ - 链表 C++ 错误(无法将 'Type' 转换为 'const ChainNode
') - ios - IGListKit - 为每个添加带有补充标题视图的多个部分
- amazon-web-services - AWS 托管页面和外部域提供商的 TLS 证书
- c# - MVC 选择下拉菜单然后更新并显示字符串
- selenium - 在空手道中调用另一个包含 webdriver 步骤的功能
- bash - 删除以#开头的行
- python - 如何使用 Lime 对时间序列进行分类
- amazon-sqs - SNS 消息的 MessageId 是否与对应的 SQS MessageId 相同?
- model - “真 U Φ”是有效的计算树逻辑公式吗?