Windows Display Driver Model (WDDM) operation flow

The following diagram shows the flow of WDDM operations that occur from when a rendering device is created to when the content is presented to the display. The information that follows the diagram describes the ordered sequence of the operation flow in more detail.

diagram illustrating the wddm operation flow.

  • Creating a Rendering Device

    After an application requests to create a rendering device:

    • 1: The DirectX Graphics Kernel Subsystem (Dxgkrnl) calls the display miniport driver's (KMD) DxgkDdiCreateDevice function.

      KMD initializes direct memory access (DMA) by returning a pointer to a filled DXGK_DEVICEINFO structure in the pInfo member of the DXGKARG_CREATEDEVICE structure.

    • 2: If the call to DxgkDdiCreateDevice succeeds, the Direct3D runtime calls the user-mode display driver's (UMD) CreateDevice function.

    • 3: In the CreateDevice call, UMD must explicitly call the runtime's pfnCreateContextCb function to create one or more GPU contexts, which are GPU threads of execution on the newly created device. The runtime returns information to UMD in the pCommandBuffer and CommandBufferSize members of the D3DDDICB_CREATECONTEXT structure to initialize the command buffer.

  • Creating Surfaces for a Device

    After an application requests to create surfaces for the rendering device:

  • Submitting the Command Buffer to Kernel Mode

    After an application requests to draw to a surface:

    • 7: The Direct3D runtime calls the UMD function related to the drawing operation, for example, DrawPrimitive2.

    • 8: The Direct3D runtime calls either the UMD's Present or Flush function to cause the command buffer to be submitted to kernel-mode. Note: UMD also submits the command buffer when the command buffer is full.

    • 9: In response to Step 8, UMD calls one of the following runtime-supplied functions:

    • 10: KMD's DxgkDdiPresent function is called if pfnPresentCb was called, or the DxgkDdiRender or DxgkDdiRenderKm function if pfnRenderCb was called. KMD validates the command buffer, writes to the DMA buffer in the hardware's format, and produces an allocation list that describes the surfaces used.

  • Submitting the DMA Buffer to Hardware

    • 11: Dxgkrnl calls KMD's DxgkDdiBuildPagingBuffer function to create special purpose DMA buffers that move the allocations specified in the allocation list to and from GPU-accessible memory. These special DMA buffers are known as paging buffers. DxgkDdiBuildPagingBuffer isn't called for every frame.

    • 12: Dxgkrnl calls KMD's DxgkDdiSubmitCommand function to queue the paging buffers to the GPU execution unit.

    • 13: Dxgkrnl calls KMD's DxgkDdiPatch function to assign physical addresses to the resources in the DMA buffer.

    • 14: Dxgkrnl calls KMD's DxgkDdiSubmitCommand function to queue the DMA buffer to the GPU execution unit. Each DMA buffer submitted to the GPU contains a fence identifier, which is a number. After the GPU finishes processing the DMA buffer, the GPU generates an interrupt.

    • 15: KMD is notified of the interrupt in its DxgkDdiInterruptRoutine function. KMD should read, from the GPU, the fence identifier of the DMA buffer that just completed.

    • 16: KMD should call the DxgkCbNotifyInterrupt function to notify the DXGK that the DMA buffer completed. KMD should also call the DxgkCbQueueDpc function to queue a deferred procedure call (DPC).