libdrm是否通过ioctl与内核DRM /图形卡通信?

问题描述

这可能是一个愚蠢的问题,因为我对此主题一无所知...看来用户应用程序可以直接与GPU对话以渲染图像,例如使用OpenGL通过mesa和libdrm,其中libdrm是各种ioctl()调用的包装,如this graph中所示。这是否意味着对于3D游戏的每个新框架,游戏应用程序都需要调用ioctl()一次(如果需要到达KMS,甚至可能两次)?这听起来像是很多用户内核之间的空间障碍(以120 fps游戏为例)。

解决方法

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

通常,用于特定操作系统(例如X11,Wayland,硬件编写器)的显示合成器软件将需要控制drm设备,这意味着无特权的应用程序无法成为DRM主设备。如果尝试使用libdrm模式设置功能的应用程序不是DRM主服务器,则大多数libdrm模式设置功能将不起作用。建议的做法是使用标准图形库(例如openGL或VULKAN)来代替应用程序,而不是直接使用libdrm。

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

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