i915, i965, dri, framebuffer, fbdev, drm, dri, minigbm, edid, virtio, SR-IOV, vulkan, mesa, virgl, kmsro,GTK

什么是DRI

DRI(Direct Rendering Infrastructure)是一个在X Windows System中允许直接访问graphics hardware的一种framework(架构),并且这种访问是安全和高效的。DRI的主要用途是为OpenGL的Mesa implementation(实现)提供硬件加速。DRI同样也对没有display server running的情况下,在framebuffer console中提供了OpenGL的加速。DRI的实现贯穿了X server和相关的client libraries, Mesa3D和DRM(Direct Rendering Manager) kernel subsystem.

 

什么是DRM

DRM(Direct Rendering Manager)是Linux kernel的子系统,用于连接现代显卡的GPU。DRM暴露给user-space的程序一个API,user-space的程序可以用这个API发送命令和数据给GPU,还进行一些操作,比如配置display的mode setting。DRM首先是作为X server的Direct Rendering Infrastructure(DRI)的kernel-space的component被开发的,但是同时也被其他graphic stack使用,比如Wayland.

User-space的programs可以用DRM的API去命令GPU做一些3D渲染的硬件加速和video decoding,也可以用作GPGPU computing。

 

什么是framebuffer

framebuffer是RAM的一部分,framebuffer是一个memory buffer,包含了所有video frame中的pixels data。可以单纯的把framebuffer看作一块内存,这部分内存包含了将要scan out显示的数据。

 

什么是 Linux framebuffer(fbdev)

等价于framebuffer driver。通常作为LCD控制器或者其他显示设备的驱动,FrameBuffer驱动是一个字符设备,设备节点是/dev/fbX,主设备号为29,次设备号递增,用户可以将Framebuffer看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer设备驱动来完成的。Framebuffer设备为上层应用程序提供系统调用,也为下一层的特定硬件驱动提供接口;那些底层硬件驱动需要用到这儿的接口来向系统内核注册它们自己。所以可以看成是一个graphic hardware-independent抽象层,上面对接应用层,下面对接LCD等硬件的驱动。 

 

什么是i915, i965, iris

i915分kernel-space的i915和use-space的i915。i915的kernel space就是intel显卡的kernel driver。i915的user-space端是intel显卡的mesa(mesa是OpenGL的开源实现)实现。

i965是intel显卡的user-space端的mesa实现。那他和i915都是mesa的实现,有什么区别呢?是因为有一些老显卡只能支持i915,而后来一些新的显卡支持i965.

iris是intel显卡的user-space端的mesa实现,那么他和i915,i965有啥区别呢?iris是比i965更加新的,是将来要替代i965的,已经被merge进了mesa的code里。

 

minigbm是HAL层,向上对接mesa的不同厂商的实现(amdgpu, iris, i965, i915)的buffer分配需求调用(gralloc)等等。向下对接kernel的buffer的申请等等。理解为是用来申请buffer的一个组件。

EDID(Extended Display Identification Data, 拓展显示屏识别数据)是一组显示设备的元数据格式,用来描述设备播放视频流的能力。EDID数据结构包含了制造商的名字,序列号(SN号),产品类型,亮度,显示大小,像素等数据。总的来说就是来描述display的一组数据。

 

virtio 是一种 I/O 半虚拟化解决方案,是一套通用 I/O 设备虚拟化的程序,是对半虚拟化 Hypervisor 中的一组通用 I/O 设备的抽象。提供了一套上层应用与各 Hypervisor 虚拟化设备(KVM,Xen,VMware等)之间的通信框架和编程接口,减少跨平台所带来的兼容性问题,大大提高驱动程序开发效率。

在完全虚拟化的解决方案中,guest VM 要使用底层 host 资源,需要 Hypervisor 来截获所有的请求指令,然后模拟出这些指令的行为,这样势必会带来很多性能上的开销。半虚拟化通过底层硬件辅助的方式,将部分没必要虚拟化的指令通过硬件来完成,Hypervisor 只负责完成部分指令的虚拟化,要做到这点,需要 guest 来配合,guest 完成不同设备的前端驱动程序,Hypervisor 配合 guest 完成相应的后端驱动程序,这样两者之间通过某种交互机制就可以实现高效的虚拟化过程。

由于不同 guest 前端设备其工作逻辑大同小异(如块设备、网络设备、PCI设备、balloon驱动等),单独为每个设备定义一套接口实属没有必要,而且还要考虑扩平台的兼容性问题,另外,不同后端 Hypervisor 的实现方式也大同小异(如KVM、Xen等),这个时候,就需要一套通用框架和标准接口(协议)来完成两者之间的交互过程,virtio 就是这样一套标准,它极大地解决了这些不通用的问题。

 

SR-IOV

SR-IOV是Single Root I/O Virtualization的缩写。

虚拟机中,一切皆虚拟。比如网卡,虚拟机看来好像有一个真实网卡,但是这个网卡是宿主机虚拟出来的硬件,也就是一堆软件代码而已,没有真实硬件。

虚拟虽然万能,但是很显然,这一堆代码是需要CPU去执行的!所以,虚拟设备的性能会随着宿主机的性能而改变,另外宿主机由于需要进行数据处理,时延等也产生了。我们之前也提到过,VT-D这个功能可以将物理的PCI-e设备直接分配给虚拟机,让虚拟机直接控制硬件,那么就可以避开上述的问题。但是,虚拟机会独占这个直通的PCI-e设备,一台宿主机可能有成百上千个虚拟机,如果每个虚拟机都给直通一个PCI-e设备,比如网卡,那么该造什么样的主机?拥有100个物理网卡的主机?想象一下也是不太可能。为了解决这个问题,Intel提出来SR-IOV这个东西。SR-IOV最初应用在网卡上。简单的说,就是一个物理网卡可以虚拟出来多个轻量化的PCI-e物理设备,从而可以分配给虚拟机使用.

SR-IOV 技术是一种基于硬件的虚拟化解决方案,可提高性能和可伸缩性。SR-IOV 标准允许在虚拟机之间高效共享 PCIe(Peripheral Component Interconnect Express,快速外设组件互连)设备,并且它是在硬件中实现的,可以获得能够与本机性能媲美的 I/O 性能。SR-IOV 规范定义了新的标准,根据该标准,创建的新设备可允许将虚拟机直接连接到 I/O 设备。单个 I/O 资源可由许多虚拟机共享。共享的设备将提供专用的资源,并且还使用共享的通用资源。这样,每个虚拟机都可访问唯一的资源。因此,启用了 SR-IOV 并且具有适当的硬件和 OS 支持的 PCIe 设备(例如以太网端口)可以显示为多个单独的物理设备,每个都具有自己的 PCIe 配置空间

 

Vulkan is by design a low-level API that removes many of the abstractions found in previous generation graphics APIs. This is great for delivering maximum performance, but has the side effect of exposing more complexity to the developer. Fortunately, several excellent tutorials exist to help clear this hurdle and get productive quickly.

 

Mesa(或者说Mesa3D)是OpenGL的实现,OpenGL是图形编程API的标准(或称规范),规定了可以实现哪些功能,而Mesa就是一种具体的实现(代码)。当然,现在Mesa里面也包含OpenCL,Vulkan等实现。

What is Virgil?

Virgil is a research project to investigate the possibility of creating a virtual 3D GPU for use inside qemu virtual machines, that allows the guest operating system to use the capabilities of the host GPU to accelerate 3D rendering. The plan is to have a guest GPU that is fully independent of the host GPU.

What exactly does it entail?

The project entails creating a virtual 3D capable graphics card for virtual machines running inside qemu. The design of this card is based around the concepts of Gallium3D to make writing Mesa and (eventually) Direct3D drivers for it easy. The card natively uses the Gallium TGSI intermediate representation for its shaders. The implementation of rendering for the card is done in the host system as part of qemu and is implemented purely on OpenGL so you can accelerated rendering on any sufficiently capable card/driver combination.

The project also consists of a complete Linux guest stack, composed of a Linux kernel KMS driver, X.org 2D DDX driver and Mesa 3D driver.

https://virgil3d.github.io/

 

# kmsro is the "kernel mode-setting render-only" support driver.
# swrast is the fallback software renderer.
# X11, DRM, and surfaceless targets are enabled
# DRI and Vulkan drivers are not supported.
# For aarch32
meson build/ --optimization s --buildtype release --prefix=/usr/local --libdir=lib/arm-linux-gnueabihf \
-Dgallium-drivers=lima,panfrost,kmsro,swrast -Dplatforms=x11,drm,surfaceless -Dvulkan-drivers= -Ddri-drivers= \
-Dllvm=false
# For aarch64
meson build/ --optimization s --buildtype release --prefix=/usr/local --libdir=lib/aarch64-linux-gnu \
-Dgallium-drivers=lima,panfrost,kmsro,swrast -Dplatforms=x11,drm,surfaceless -Dvulkan-drivers= -Ddri-drivers= \
-Dllvm=false

VirtIO-GPU

VirtIO-GPU是一种API forwarding的方案。它的基本原理是将客户机中的OpenGL或Vulkan API调用请求转发到宿主机上的virglrenderer库进行处理,并通过virtqueue机制将处理结果返回给客户机。

具体来说,当虚拟机中的应用程序发起一个图形API调用请求时,虚拟化GPU驱动程序会将该请求转化为一个或多个命令,并将这些命令按顺序打包成一个command stream。command stream通常以二进制格式存储,其中每个命令包含有关调用请求的详细信息,例如所调用的函数名称、函数参数、纹理数据等等。在将命令流发送到宿主机上的virglrenderer库之前,虚拟化GPU驱动程序通常还需要进行一些额外的处理。例如,它可能需要将命令流分成多个小块进行传输,以便在网络传输过程中提高传输效率和可靠性。此外,驱动程序还可能需要对一些命令进行优化,例如将多个draw call命令合并成一个batch命令,以提高性能。

在VirtIO-GPU方案中,客户机中的虚拟化GPU驱动程序会将OpenGL或Vulkan API调用请求打包成一个命令流(command stream),并将其传输到宿主机中的virglrenderer库。virglrenderer库会将命令流解析成OpenGL或Vulkan API调用,并将其在宿主机中执行。执行结果会被打包成一个命令流,并通过virtqueue机制传输回客户机。

通过API forwarding,VirtIO-GPU可以提供虚拟化GPU设备,并且可以在客户机中使用原生的OpenGL或Vulkan API进行操作,从而提高了性能和兼容性。同时,VirtIO-GPU方案还可以在宿主机上利用硬件加速等技术提高图形性能,从而进一步提升虚拟机的性能。

总之,VirtIO-GPU是一种基于API forwarding的方案,它将客户机中的OpenGL或Vulkan API调用请求转发到宿主机上的virglrenderer库进行处理,并通过virtqueue机制进行通信。这种方案可以提供虚拟化GPU设备,并且可以在客户机中使用原生的OpenGL或Vulkan API进行操作,提高了性能和兼容性。

virto-gpu 技术将 OpenGLES 命令导出(virgl, virgl是一种OpenGL的实现,类与i965)之后再反过来调用宿主侧的 virglrenderer,又将其翻译回 OpenGL 和 GLSL,然后再调用宿主的 OpenGL,这部分技术代表是 Qemu 方案。使用假的抽象 GPU。在抽象层 GPU 层进行拦截,并调用宿主侧的 GPU。

对于图中的理解是,对于Virgl,由于Virgl本身的目的是为了做一个虚拟的3D graphics card,用以独立与host的graphics card,而作为一个显卡,无论是虚拟的还是真实的,都得有一个OpenGL的实现,比如Intel的i965。恰巧virtiog-gpu方案中需要把OpenGL命令转换成command stream用virtqueue的方式传递给hypervisor(QEMU),于是mesa干脆就利于了virgl这个opengl的实现去做转换工作,这样成功避免了依赖于某个vendor(Intel、AMD等)的OpenGL实现。

 

posted @ 2021-04-26 16:47  青山牧云人  阅读(3732)  评论(0编辑  收藏  举报