Windows Display Driver Model (WDDM) Operation Flow(MSDN翻译)

Windows Display Driver Model (WDDM) Operation Flow

下图显示了WDDM从渲染设备的创建到内容被显示的流程。

Windows Display Driver Model (WDDM) Operation Flow(MSDN翻译)_第1张图片

Creating a Rendering Device

1.

在应用程序请求创建渲染设备之后,KMD会收到DxgkDdiCreateDevice调用DxgkDdiCreateDevice调用。KMD会初始化DMA信息(PS:包含DMA buffer大小等信息),将其指针填充DXGKARG_CREATEDEVICE 中的DXGK_DEVICEINFO(PS:其中会包含KMD Process的句柄)类型的pInfo成员,

2.

如果调用KMD DxgkDdiCreateDevice成功,MSFT D3D RT 会调用UMD的CreateDevice。

3.

在CreateDevice中,UMD必须显式调用pfnCreateContextCb来创建一个或多个Context - 代表创建新设备上执行的GPU 线程。D3D RT在D3DDDICB_CREATECONTEXT的  pCommandBuffer 和 CommandBufferSize 发成员中返回Command Buffer的信息用于初始化Command Buffer。

Creating Surfaces for a Device

4.

在Application请求创建渲染设备使用的Surface之后,D3D RT会调用UMD的CreateResource。

5.

UMD的CreateResource中会调用RT 的 pfnAllocateCb。

6.

KMD在收到DxgkDdiCreateAllocation时,会指定创建allocation的类型和数量。DxgkDdiCreateAllocation 会返回关于Allocation的信息,该信息保存在DXGKARG_CREATEALLOCATION的成员 DXGK_ALLOCATIONINFO类型数组 pAllocationInfo中。

Submitting the Command Buffer to Kernel Mode

7.

在Application请求在surface上绘制时,D3D RT会调用UMD中关于绘制的的函数, 例如DrawPrimitive2。

8.

D3D RT会调用UMD的Present或Flush来提交Command Buffer给KMD。如果Command buffer被写满UMD也会提交Command buffer。

9.

UMD会在Present被调用时,调用RT提供的pfnPresentCb函数,或者在command buffer被写满或被调用Flush时调用pfnRenderCb函数。

10.

如果调用了RT的pfnPresent函数, 则DXGK会调用KMD的DxgkDdiPresent函数,或者,调用RT的pfnRenderCb被调用时,DXGK会调用KMD的DxgkDdiRender或DxgkDdiRenderKm函数。KMD会校验Command buffer并转换成硬件能识别的内容写入DMA buffer中,同时会产生allocation list,其中描述了DMA buffer中使用到的Surface资源。

Submitting the DMA Buffer to Hardware

11.

MSFT DXGK子系统会调用KMD的DxgkDdiBuildPagingBuffer 来创建特殊功能的DMA buffer,即Paging Buffer,其中的命令会将allocation list里面指定的allocation移出或移进到 GPU 能够访问的内存中。

Note DXGK不会为每一帧调用DxgkDdiBuildPagingBuffer

12.

DXGK子系统调用KMD的DxgkDdiSubmitCommand函数来将Paging Buffer插入GPU的执行单元的队列中。

13.

DXGK调用KMD的DxgkDdiPatch函数来为DMA buffer中的资源指定物理地址。

14.

DXGK调用KMD的DxgkDdiSubmitCommand来将DMA buffer插入到GPU 执行单元的队列之中。每个被提交的DMA buffer包含一个Fence id,该ID为一个数字。再GPU处理完DMA buffer之后, GPU会生成一个中断。

15.

DXGK会调用 KMD的DxgkDdiInterruptRoutine来通知中断。KMD应该从GPU硬件中读取刚刚完成的DMA buffer 的 fence id。

16.

KMD应该再DMA buffer执行完成时调用DxgkCbNotifyInterrupt来通知DXGK。同时,KMD应该调用DxgkCbQueueDpc插入一个任务到DPC队列中。(PS:会在其中处理有关刚完成的DMA buffer相关的处理, 因为不应该在中断中处理太多事务)

你可能感兴趣的:(WDDM)