这可能是一个愚蠢的问题,因为我对这个主题了解不多。。。用户应用程序似乎可以通过mesa和libdrm直接与GPU对话以渲染图像,例如使用OpenGL,其中libdrm是各种ioctl((调用的包装器,如图所示。这是否意味着,对于3D游戏的每一个新帧,游戏应用程序都需要调用ioctl((一次(如果需要访问KMS,甚至可能调用两次(?这听起来像是在跨越用户内核空间的障碍(想想120帧/秒的游戏(。
libdrm是一个用户空间包装器,用于对底层KMS驱动程序功能进行细粒度访问,如模式设置、检查所使用的平面是覆盖平面还是主平面等,因为运行在内核中的h/w驱动程序往往支持与标准功能不同的一组功能。使用libdrm的标准方法是打开/dev/
节点中可用的drm设备,并使用open()
返回的fd执行libdrm函数调用。
通常情况下,用于特定操作系统的显示合成器软件,如X11、wayland、硬件合成器,将需要控制drm设备,这意味着非特权应用程序无法成为drm主机。如果尝试使用libdrm模式设置功能的应用程序不是DRM主机,则大多数功能都不起作用。建议使用标准图形库(如openGL或VULKAN(在应用程序中准备和渲染帧,而不是直接使用libdrm。
与内核DRM模块交互所需的ioctl数量很可能不是您在尝试渲染高FPS应用程序时面临的最大瓶颈。在与目标系统的显示合成器协作的同时运行高fps应用程序的首选方式是具有
- 用于渲染的双缓冲区或三缓冲区设置,在当前帧完成渲染之前,下一个要渲染的缓冲区已准备好进行渲染
- 尽可能利用h/w加速,例如执行缩放/调整大小/图像格式转换/颜色空间转换
- 预计算和重用着色器元素
- 尽量重用纹理元素,而不是为渲染的每一帧计算大量纹理
- 尽可能使用矢量/SSIMD/SSEv2,3,4/AVX/neon指令来利用现代CPU流水线