唉。死不悔改,而且一错再错。
首先,问题是错的。我在另一个帖子里
Windows 10 给 Linux 子系统写显卡驱动的是一个人吗,是谁呢?提到的是Direct3D9/11的驱动,是给Drawbridge写的,而不是Linux子系统。他们在发展上有个先后的关系,但不是一个东西。题主对此完全一知半解的情况下,不仔细看就断章取义,实在太胡搅蛮缠。
其次,不撸兔子的说法,基本每个点都是错误的。
「parrallels的虚拟显卡最多只是把OpenGL调用转发到宿主机上。「
不,那么做行不通。(甚至parallels都拼错了)
」Linux子系统和Windows子系统在内核看来是同等地位的。应该不需要搞这套东西才对。」
不,Linux子系统在Picoprocess里。Linux子系统和Windows本身是guest和host的关系。
「不提供CUDA真正的原因肯定不是不想做。而是已经做好了」
不,根本没写。而且如果你懂CUDA的话,就知道转API容易,难点是显存访问和管理。
「只是把Library OS里面的调用转发到外面。「
不,那么做行不通。
好了,现在我就来说说为什么直接把API调用转到外面行不通。会有很多细节,像题主和不撸兔子这样没做过的人根本不会了解。
1. 流量。
API调用看似简单,只要把所有的API都转出去,就行了。原先远程桌面就是这么做的。但缺点是,API调用所要消耗的流量远大于在驱动层搞。举个例子,把同一个设置状态调用两次,你就得在API层转两次。最多就是cache一下,把变化的传了。而在D3D的体系里,有runtime做状态管理,只会把真正修改了有起作用的状态往下传给驱动,并会做严格的状态验证。所以在驱动层,你所需要转的数据远少于API层。
2. 出错控制。
如果运行过程出了严重问题,你需要的是不让host crash,最多让guest crash。如果从API层走,那么这件事情无法避免。如果guest里有多了个验证,就会把错误留在子系统,而不会传出来。
3. bug-to-bug兼容
如果只是API层,那么要求guest和host的runtime完全一致,才可以保证100%兼容。而从驱动走,runtime是在guest,那么只要都符合WDDM,就没问题。guest和host的runtime可以解耦。
4. 什么是驱动。
驱动不在于你怎么实现,你是直接去真实硬件,还去了虚拟硬件。只要是按照驱动的规范实现、编译、部署,系统看到的是个设备,那就是驱动。我给Drawbridge写的第一版,是可以在普通的Windows上装的,你能在设备管理器里看到多了一块显卡,程序可以在上面建立设备,进行渲染。(由于没有实现电源管理的部分,在休眠后会睡死)
这里放一张WDDM的架构图。驱动需要实现的是user-mode display driver(UMD)和Display miniport driver(KMD)。OpenGL installable client driver属于可选。