libdrm 是否通过 ioctl() 与内核 DRM/graphics 卡通信?

Does libdrm talk to kernel DRM/graphics card via ioctl()?

这可能是一个愚蠢的问题,因为我对这个话题一点也不了解...似乎用户应用程序可以直接与 GPU 对话以渲染图像,例如使用 OpenGL,通过 mesa 和 libdrm,其中 libdrm 是各种 ioctl() 调用的包装器,如 this graph 中所示。这是否意味着对于 3D 游戏的每个新帧,游戏应用程序都需要调用 ioctl() 一次(如果需要达到 KMS,甚至可能调用两次)?这听起来像是很多用户内核 space 障碍穿越(考虑 120 fps 游戏)。

libdrm 是一个用户 space 包装器,用于对底层 KMS 驱动程序功能进行细粒度访问,例如模式设置、检查正在使用的平面是覆盖平面还是主平面等。libdrm 实现通常因各种不同而不同CPU/GPU/OS 组合,因为内核中的 h/w 驱动程序 运行ning 倾向于支持与标准功能不同的功能集。使用 libdrm 的标准方法是打开 /dev/ 节点中可用的 drm 设备,并使用从 open().

返回的 fd 执行 libdrm 函数调用

通常情况下,特定 OS 的显示合成器软件如 X11、wayland、hardware-composer 需要控制 drm 设备,这意味着非特权应用程序没有权限成为 DRM 大师的方式。如果尝试使用它们的应用程序不是 DRM 主机,则大多数 libdrm 模式设置功能将不起作用。推荐的做法是使用 openGL 或 VULKAN 等标准图形库来准备和渲染应用程序中的帧,而不是直接使用 libdrm。

与内核 DRM 模块交互所需的 ioctl 数量很可能不是您在尝试呈现高 FPS 应用程序时将面临的最大瓶颈。在与目标系统的显示合成器合作时,运行 高 fps 应用程序的首选方法是

  • 用于渲染的双缓冲或三缓冲设置,其中要渲染的下一个缓冲区在当前帧完成渲染之前准备好渲染。
  • 尽可能利用 h/w 加速,例如执行 scaling/resizing/image 格式 conversions/color space 转换。
  • 预计算和重用着色器元素
  • 尝试尽可能多地重复使用纹理元素,而不是为正在渲染的每一帧计算大量纹理。
  • 尽可能使用 vector/SIMD/SSEv2,3,4/AVX/neon 指令以利用现代 CPU 管道