Fluxo de operação WDDM (Windows Display Driver Model)
O diagrama a seguir mostra o fluxo de operações WDDM que ocorrem desde quando um dispositivo de renderização é criado até quando o conteúdo é apresentado à exibição. As informações que seguem o diagrama descrevem a sequência ordenada do fluxo de operação com mais detalhes.
Criando um dispositivo de renderização
Depois que um aplicativo solicita a criação de um dispositivo de renderização:
1: O DirectX Graphics Kernel Subsystem (Dxgkrnl) chama a função DxgkDdiCreateDevice do driver de miniporta de exibição do modo kernel (KMD).
O KMD inicializa o acesso direto à memória (DMA) retornando um ponteiro para uma estrutura de DXGK_DEVICEINFO preenchida no membro pInfo da estrutura DXGKARG_CREATEDEVICE.
2: Se a chamada para DxgkDdiCreateDevice for bem-sucedida, o tempo de execução do Direct3D chamará a função CreateDevice do driver de exibição do modo de usuário (UMD).
3: Na chamada CreateDevice, o UMD deve chamar explicitamente a função pfnCreateContextCb do tempo de execução para criar um ou mais contextos de GPU, que são threads de execução de GPU no dispositivo recém-criado. O tempo de execução retorna informações para UMD nos membros pCommandBuffer e CommandBufferSize da estrutura D3DDDICB_CREATECONTEXT para inicializar o buffer de comando.
Criando superfícies para um dispositivo
Após uma solicitação de aplicativo para criar superfícies para o dispositivo de renderização:
4: O tempo de execução do Direct3D chama a função CreateResource do UMD.
5: CreateResource chama a função pfnAllocateCb fornecida em tempo de execução.
6: O tempo de execução chama a função DxgkDdiCreateAllocation do KMD, especificando o número e os tipos de alocações a serem criadas. DxgkDdiCreateAllocation retorna informações sobre as alocações em uma matriz de estruturas DXGK_ALLOCATIONINFOno membro pAllocationInfo da estrutura DXGKARG_CREATEALLOCATION.
Enviando o buffer de comando para o modo kernel
Após uma solicitação de aplicativo para desenhar em uma superfície:
7: O tempo de execução do Direct3D chama a função UMD relacionada à operação de desenho, por exemplo, DrawPrimitive2.
8: O tempo de execução do Direct3D chama a função Presente ou Flush do UMD para fazer com que o buffer de comandos seja enviado para o modo kernel. Nota: UMD também envia o buffer de comando quando o buffer de comando está cheio.
9: Em resposta à Etapa 8, o UMD chama uma das seguintes funções fornecidas pelo tempo de execução:
- A função pfnPresentCb do tempo de execução se Present foi chamada.
- A função pfnRenderCb do tempo de execução se Flush foi chamado ou o buffer de comando está cheio.
10: A função DxgkDdiPresent do KMD é chamada se pfnPresentCb foi chamada, ou a função DxgkDdiRender ou DxgkDdiRenderKm se pfnRenderCb foi chamada. O KMD valida o buffer de comandos, grava no buffer DMA no formato do hardware e produz uma lista de alocação que descreve as superfícies usadas.
Enviando o buffer DMA para o hardware
11: Dxgkrnl chama a função DxgkDdiBuildPagingBuffer do KMD para criar buffers DMA de propósito especial que movem as alocações especificadas na lista de alocação de e para a memória acessível pela GPU. Esses buffers DMA especiais são conhecidos como buffers de paginação. DxgkDdiBuildPagingBuffer não é chamado para todos os quadros.
12: Dxgkrnl chama a função DxgkDdiSubmitCommand do KMD para enfileirar os buffers de paginação para a unidade de execução da GPU.
13: Dxgkrnl chama a função DxgkDdiPatch do KMD para atribuir endereços físicos aos recursos no buffer DMA.
14: Dxgkrnl chama a função DxgkDdiSubmitCommand do KMD para enfileirar o buffer DMA para a unidade de execução da GPU. Cada buffer DMA enviado à GPU contém um identificador de cerca, que é um número. Depois que a GPU terminar de processar o buffer DMA, a GPU gerará uma interrupção.
15: KMD é notificado da interrupção em sua função DxgkDdiInterruptRoutine . O KMD deve ler, a partir da GPU, o identificador de cerca do buffer DMA que acabou de ser concluído.
16: KMD deve chamar DxgkCbNotifyInterrupt para notificar o DXGK que o buffer DMA foi concluído. O KMD também deve chamar DxgkCbQueueDpc para enfileirar uma chamada de procedimento adiado (DPC).