英文:
Where do Vulkan functions live?
问题
I am trying to wrap my head around Vulkan and how it works at low level. I played around and read some of the APİ documentation. Also read some blogs about it. As far as I know Vulkan is just an API spec. There is no implementation in any language on Vulkan's website. SDK is there to discover the driver's .lib or .so files and then call them on your program. Driver's are implemented by vendors so I think I will not be able to read the source code. So basically is this what happens:
SDK discovers driver implementation -> I call driver's implementation -> Compiled code communicates to GPU -> Magic happens
I am trying to get my understanding of GPU pipeline a little bit better and I am not experienced in GPU field that much. When we compile the code we write it is usually compiled for platform or VM that is going to be used but where does GPU code go? How can I communicate with GPU at hardware level? Is this possible without using APIs?
According to my basic research some driver's implement it reading a certain part of RAM that is dedicated for GPU communication, some driver's directly compile the code and load and such. I am really lost on this and there is not much information on the web, assuming most of these stuff vendor specific.
英文:
I am trying to wrap my head around Vulkan and how it works at low level. I played around and read some of the APİ documentation. Also read some blogs about it. As far as I know Vulkan is just an API spec. There is no implementation in any language on Vulkan's website. SDK is there to discover the driver's .lib or .so files and then call them on your program. Driver's are implemented by vendors so I think I will not be able to read the source code. So basically is this what happens:
SDK discovers driver implementation -> I call driver's implementation -> Compiled code communicates to GPU -> Magic happens
I am trying to get my understanding of GPU pipeline a little bit better and I am not experienced in GPU field that much. When we compile the code we write it is usually compiled for platform or VM that is going to be used but where does GPU code go? How can I communicate with GPU at hardware level? Is this possible without using APIs?
According to my basic research some driver's implement it reading a certain part of RAM that is dedicated for GPU communication, some driver's directly compile the code and load and such. I am really lost on this and there is not much information on the web, assuming most of these stuff vendor specific.
答案1
得分: 3
我只能提供Win32驱动环境的信息,但原则可以应用到其他操作系统。
在编写Vulkan应用程序时,您会链接到Vulkan加载器(vulkan-1.dll)。加载器会搜索注册表以查找每个GPU制造商的Vulkan可安装客户端驱动程序(ICD)的位置,ICD导出了一些函数,如vk_icdGetInstanceProcAddr
和vk_icdGetPhysicalDeviceProcAddr
。加载器有一些公开导出的函数(大多来自Vulkan 1.0规范),但大多数是通过函数vkGetInstanceProcAddr
和vkGetDeviceProcAddr
获取的,加载器将为每个函数生成一个完整的链,它将通过实现该函数的每个层次进行下降,最终着陆在ICD上。您可以在Vulkan Loader Interface规范中了解更多信息。
至于与GPU的通信,这由内核模式驱动程序处理,在Windows上通常是Display Miniport Driver。几乎所有GPU都是PCIe设备(即使是集成型的),而所有的“魔法”实际上只是内存映射IO。通常有一块内存,其中包含实际的VRAM和控制块。控制块有许多“寄存器”,实际上只是内存地址,当读取或写入时会触发GPU内的特殊操作。这也在嵌入式开发中随处可见,因此通常更适合研究这个概念。GPU的PCIe控制器处理所有读取和写入请求,因此它可以在收到此类请求时触发任何操作。常见的简单寄存器是复位寄存器,当从中读取时,会导致GPU的当前状态复位。
在Windows上,这两者之间的通信是通过GDI32.dll执行的。它只导出了大多数仅触发中断/系统调用的函数,这将进入dxgkrnl.sys,然后调用Display Miniport Driver。
Direct3D以类似的方式执行操作,但使用回调模型,不需要使用GDI32.dll与dxgkrnl.sys通信。
整个流程在Microsoft的WDDM文档中有解释。该文档没有提到Vulkan,但实际上与OpenGL的描述相同。
对于编写Vulkan应用程序,这些都不是很重要。您唯一需要知道的是,Vulkan的真正实现由每个GPU供应商执行,他们将处理所有关于在GPU上运行您的命令和着色器的细微差别。因为所有这些用户模式API都是供供应商专门用于与其GPU通信的,所以实际上没有直接与GPU通信的方式,这就是这些API的用途。
英文:
I can only speak to the Win32 driver environment, but the principles will carry over to other operating systems.
When you write a Vulkan application you link against the Vulkan loader (vulkan-1.dll). The loader searches the registry for some specific keys to find where each GPU manufacturer has their Vulkan Installable Client Driver (ICD). The ICD exports a handful of functions such as vk_icdGetInstanceProcAddr
and vk_icdGetPhysicalDeviceProcAddr
. The loader has a few functions which are publicly exported (mostly from the Vulkan 1.0 spec), but most are acquired through the functions vkGetInstanceProcAddr
and vkGetDeviceProcAddr
, the loader will generate a whole chain for every function, whereby it will descend through every layer that implements an intercept for that function, finally landing at the ICD. You can read more about this in the Vulkan Loader Interface<sub>archive</sub> spec.
As for communication with the GPU, that is handled by a kernel mode driver, on Windows that would be the Display Miniport Driver. Almost all GPUs are PCIe devices (even integrated ones), and all the "magic" is really just Memory-Mapped IO. There's usually a block of memory which is the actual VRAM, and a control block. The control block has a lot of "register", which are really just memory addresses, that when read or written to trigger special actions within the GPU. This also shows up everywhere in embedded development, so that's usually a better avenue to research the concept. The GPU's PCIe controller handles all read and write requests, so it can trigger any action it wants when it receives such a request. A common simple register is a reset register, which when read from causes the GPU's current state to reset.
Communication between these two on Windows is performed with GDI32.dll. It just exports a lot of functions that mostly just trigger an interrupt/syscall, that will go into dxgkrnl.sys, which will call the Display Miniport Driver.
Direct3D does things in a similar way, except they use a callback model, and don't need to use GDI32.dll to communicate with dxgkrnl.sys.
The whole flow is explained on Microsoft's documentation for WDDM<sub>archive</sub>. There documentation doesn't mention Vulkan, but it's essentially the same flow as is described for OpenGL.
None of this really matters for writing a Vulkan application. All you really need to know is that the real meat of Vulkan is implemented by each GPU vendor, and they'll handle all the nuance of getting your commands and shaders to run on the GPU. Because all of these user mode API's are implemented by the vendors specifically for communicating with their GPU, there really isn't a way to communicate with the GPU directly, that's what these API's are for.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论