Windows 显示驱动程序模型 (WDDM) 操作流
下图显示了从创建呈现设备到显示内容时发生的 WDDM 操作流。 关系图后面的信息更详细地描述了操作流的有序顺序。
创建呈现设备
在应用程序请求创建呈现设备之后:
1:DirectX 图形内核子系统 (Dxgkrnl) 调用显示微型端口驱动程序的 (KMD) DxgkDdiCreateDevice 函数。
KMD 通过返回指向 DXGKARG_CREATEDEVICE 结构的 pInfo 成员中填充的DXGK_DEVICEINFO结构的指针, (DMA ) 初始化直接内存访问。
2:如果对 DxgkDdiCreateDevice 的调用成功,Direct3D 运行时将调用用户模式显示驱动程序的 (UMD) CreateDevice 函数。
3:在 CreateDevice 调用中,UMD 必须显式调用运行时的 pfnCreateContextCb 函数,以创建一个或多个 GPU 上下文,它们是在新创建的设备上执行的 GPU 线程。 运行时将D3DDDICB_CREATECONTEXT结构的pCommandBuffer 和 CommandBufferSize 成员中的信息返回到 UMD,以初始化命令缓冲区。
为设备创建图面
在应用程序请求为呈现设备创建图面之后:
4:Direct3D 运行时调用 UMD 的 CreateResource 函数。
5: CreateResource 调用运行时提供的 pfnAllocateCb 函数。
6:运行时调用 KMD 的 DxgkDdiCreateAllocation 函数,指定要创建的分配的数量和类型。 DxgkDdiCreateAllocation 返回有关 DXGKARG_CREATEALLOCATION 结构的 pAllocationInfo 成员中 DXGK_ALLOCATIONINFO 结构数组中的分配信息。
将命令缓冲区提交到内核模式
在应用程序请求绘制到图面之后:
7:Direct3D 运行时调用与绘图操作相关的 UMD 函数,例如 DrawPrimitive2。
8:Direct3D 运行时调用 UMD 的 Present 或 Flush 函数,使命令缓冲区提交到内核模式。 注意:当命令缓冲区已满时,UMD 还会提交命令缓冲区。
9:为了响应步骤 8,UMD 调用以下运行时提供的函数之一:
- 如果调用 Present,则运行时的 pfnPresentCb 函数。
- 如果调用 Flush 或命令缓冲区已满,则运行时的 pfnRenderCb 函数。
10:如果调用 pfnPresentCb,则调用 KMD 的 DxgkDdiPresent 函数;如果调用 pfnRenderCb,则调用 DxgkDdiRender 或 DxgkDdiRenderKm 函数。 KMD 验证命令缓冲区,以硬件的格式写入 DMA 缓冲区,并生成描述所用图面的分配列表。
将 DMA 缓冲区提交到硬件
11: Dxgkrnl 调用 KMD 的 DxgkDdiBuildPagingBuffer 函数来创建特殊用途 DMA 缓冲区,用于将分配列表中指定的分配移入 GPU 可访问的内存和从中移动。 这些特殊的 DMA 缓冲区称为分页缓冲区。 DxgkDdiBuildPagingBuffer 不是针对每个帧调用的。
12: Dxgkrnl 调用 KMD 的 DxgkDdiSubmitCommand 函数,将分页缓冲区排队到 GPU 执行单元。
13: Dxgkrnl 调用 KMD 的 DxgkDdiPatch 函数,将物理地址分配给 DMA 缓冲区中的资源。
14: Dxgkrnl 调用 KMD 的 DxgkDdiSubmitCommand 函数,将 DMA 缓冲区排队到 GPU 执行单元。 提交到 GPU 的每个 DMA 缓冲区都包含一个围栏标识符,该标识符是一个数字。 GPU 处理完 DMA 缓冲区后,GPU 将生成中断。
15:KMD 在其 DxgkDdiInterruptRoutine 函数中收到中断通知。 KMD 应从 GPU 读取刚刚完成的 DMA 缓冲区的围栏标识符。
16:KMD 应调用 DxgkCbNotifyInterrupt 函数,以通知 DXGK DMA 缓冲区已完成。 KMD 还应调用 DxgkCbQueueDpc 函数,将延迟过程调用 (DPC) 排队。
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈