libdrm 是否通过 ioctl() 与内核 DRM/显卡对话?

QnA*_*QnA 3 c graphics ioctl drm linux-kernel

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

SCC*_*CCC 6

libdrm 是一个用户空间包装器,用于对底层 KMS 驱动程序功能执行细粒度访问,例如模式设置、检查所使用的平面是覆盖平面还是主平面等。对于各种 CPU/GPU/OS 组合,libdrm 实现通常有所不同,因为在内核中运行的硬件驱动程序往往支持除标准功能之外的不同功能集。使用 libdrm 的标准方法是打开/dev/节点中可用的 drm 设备并使用从返回的 fd 执行 libdrm 函数调用open().

通常,特定操作系统(如 X11、wayland、hardware-composer)的显示合成器软件需要控制 drm 设备,这意味着非特权应用程序无法成为 DRM 主控。如果尝试使用它们的应用程序不是 DRM 主控,则大多数 libdrm 模式设置功能将不起作用。建议的做法是使用 openGL 或 VULKAN 等标准图形库在应用程序中准备和渲染帧,而不是直接使用 libdrm。

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

  • 用于渲染的双缓冲或三缓冲设置,其中要渲染的下一个缓冲区在当前帧完成渲染之前准备好渲染。
  • 尽可能利用硬件加速,例如执行缩放/调整大小/图像格式转换/色彩空间转换。
  • 预计算并重用着色器元素
  • 尝试尽可能多地重用纹理元素,而不是为渲染的每个帧计算大量纹理。
  • 尽可能使用矢量/SIMD/SSEv2,3,4/AVX/neon 指令,以利用现代 CPU 管道