Compartilhar via


TDR em Windows 8 e posterior

Começando com Windows 8, o comportamento de TDR (detecção e recuperação de tempo limite de GPU) permite que partes de adaptadores físicos individuais sejam redefinidas, em vez de exigir uma redefinição em todo o adaptador.

Consulte TDR (detecção e recuperação de tempo limite) para obter mais informações sobre TDR.

Requisitos

  • Versão mínima do WDDM: 1.2
  • Versão mínima do Windows: 8
  • Implementação do driver – Elementos gráficos completos e Somente renderização: obrigatório
  • Requisitos e testes da WHLK: Device.Graphics... TDRResiliency

DDI (interface de driver de dispositivo) TDR

Para acomodar essa alteração de comportamento, os drivers de miniporto de exibição implementam estas funções:

Um driver de miniporta de exibição indica suporte para essas funções definindo o DXGK_DRIVERCAPS. Membro SupportPerEngineTDR , nesse caso, ele deve implementar todas as funções acima.

Observação

Um driver que dá suporte a essas funções também deve dar suporte à sincronização de nível zero para a função DxgkDdiCollectDbgInfo . Isso é para garantir que as chamadas de miniporto de nível zero não afetadas pela operação de redefinição possam continuar. Consulte Comentários de DxgkDdiCollectDbgInfo.

As seguintes estruturas estão associadas às funções acima:

Nós

Conforme usado nas funções TDR acima, um é uma das várias partes de um único adaptador físico que pode ser agendado independentemente. Por exemplo, um nó 3D, um nó de decodificação de vídeo e um nó de cópia podem existir no mesmo adaptador físico e cada um pode receber um valor ordinal de nó separado no DXGKARG_QUERYDEPENDENTENGINEGROUP. Membro NodeOrdinal em uma chamada para DxgkDdiQueryDependentEngineGroup.

O número de nós no adaptador físico é relatado pelo driver de miniporta de exibição no membro NbAsymetricProcessingNodes do DXGK_DRIVERCAPS. GpuEngineTopology.

O valor ordinal do nó é passado no membro NodeOrdinal da estrutura DXGKARG_CREATECONTEXT quando um contexto é criado.

Motores

Conforme usado nas funções TDR acima, um mecanismo é um dos vários adaptadores físicos (ou GPUs) que juntos atuam como um adaptador lógico. O subsistema de kernel de elementos gráficos DirectX dá suporte a essas configurações, mas exige que cada mecanismo tenha o mesmo número de nós.

Por exemplo, o agendador de GPU considera o mecanismo 0 para corresponder ao adaptador físico 0. O mecanismo 0 deve ter o mesmo número de nós que o mecanismo 1, que corresponde ao adaptador 1.

Valor ordinal do mecanismo na criação do contexto

Quando um contexto é criado, um único bit correspondente ao valor ordinal do mecanismo é definido no membro EngineAffinity da estrutura DXGKARG_CREATECONTEXT . O membro EngineOrdinal dessa e de outras estruturas relacionadas ao agendador é um índice baseado em zero. O valor de EngineAffinity é 1 <<EngineOrdinal e EngineOrdinal é a posição de bit mais alta em EngineAffinity.

Pacotes não afetados pela redefinição do mecanismo

O driver pode ser solicitado pelo agendador de GPU a reenviar pacotes que foram enviados tarde demais para que a fila de hardware do mecanismo seja totalmente processada antes que a redefinição do mecanismo seja concluída. O driver deve seguir estas diretrizes para reenviar esses pacotes:

  • Paginação de pacotes: o driver será solicitado pelo agendador de GPU a reenviar pacotes de paginação com suas IDs de limite originais e na mesma ordem em que foram originalmente enviados. Esses pacotes serão reenviados antes que novos pacotes sejam adicionados à fila de hardware.
  • Renderizar pacotes: o agendador de GPU atribuirá novos IDs de limite de pacotes de renderização e, em seguida, os reenviará.

Sequência de chamadas para redefinir um mecanismo

Quando DxgkDdiResetEngine é bem-sucedido, o agendador de GPU garante que o valor LastAbortedFenceId retornado da chamada de redefinição do mecanismo corresponda a uma ID de cerca existente na fila de hardware ou à última ID de limite concluída na GPU. A última situação pode acontecer quando a fila de hardware esvazia depois que o tempo limite da GPU é detectado, mas antes que o retorno de chamada de redefinição do mecanismo seja invocado.

O último valor de ID de limite concluído na GPU deve ser mantido pelo driver o tempo todo porque ele também é necessário para definir o membro DmaPreempted.LastCompletedFenceId de uma estrutura de notificação de interrupção de preempção DXGKARGCB_NOTIFY_INTERRUPT_DATA . A última ID de limite concluída deve ser avançada somente nestas situações:

  • Quando um pacote é concluído (não antecipado), a última ID de cerca concluída deve ser definida como a ID de limite do pacote concluído.
  • Quando DxgkDdiResetEngine for bem-sucedido, a última ID de cerca concluída deverá ser definida como o valor do membro LastCompletedFenceId retornado pela chamada de redefinição do mecanismo.
  • Para redefinição em todo o adaptador, a última ID de limite concluída em todos os nós deve ser avançada para a última ID de cerca enviada no momento da redefinição.

Aqui está uma sequência cronológica de uma redefinição bem-sucedida do mecanismo, conforme visto pelo agendador de GPU:

  1. Uma tentativa de preempção é emitida.

  2. Um tempo limite de GPU é detectado.

  3. Uma instantâneo das últimas IDs de limite enviadas e concluídas é obtida pelo agendador de GPU e as interrupções do mecanismo com tempo limite são ignoradas. Esta é uma operação atômica no nível de interrupção do dispositivo.

  4. Se não houver pacotes na fila de hardware neste momento, saia. Isso pode acontecer se um pacote foi concluído na janela de tempo entre as etapas 2 e 3.

  5. Todos os DPCs na fila são liberados.

  6. Prepare-se para a redefinição do mecanismo.

  7. Chame DxgkDdiResetEngine.

  8. Se o membro LastAbortedFenceId for menor que a última ID de cerca concluída ou for maior que a última ID de limite enviada, o subsistema de kernel de elementos gráficos DirectX fará com que ocorra uma verificação de bugs do sistema. Em um arquivo de despejo de memória, o erro é observado pela mensagem BugCheck 0x119, que tem estes quatro parâmetros:

    • 0xA, o que significa que o driver relatou uma ID de cerca anulada inválida
    • Valor LastAbortedFenceId retornado pelo driver
    • Última ID de cerca concluída
    • Um parâmetro interno do sistema operacional
  9. Se o valor LastAbortedFenceId for válido, prossiga com a recuperação de redefinição do mecanismo da seguinte maneira. Se um pacote de paginação tiver sido afetado pela redefinição do mecanismo, o agendador de GPU seguirá a redefinição do mecanismo com uma redefinição em todo o adaptador. Todos os dispositivos que possuem alocações referenciadas por esse pacote de paginação também são colocados no estado de erro. No entanto, o próprio dispositivo do sistema não é colocado no estado de erro e retoma a execução após a conclusão da redefinição.

Casos especiais

Uma situação especial pode ocorrer quando um pacote é concluído na GPU entre as etapas 3 e 7 descritas acima. Nesse caso, LastAbortedFenceId deve ser definido pelo driver como a ID de limite do último pacote concluído se não houver pacotes na fila de hardware do ponto de vista do driver. Do ponto de vista do agendador, será exibido que esse pacote foi anulado e o dispositivo correspondente será colocado em um estado de erro, mesmo que o pacote tenha sido concluído.

Se o driver não puder executar uma operação de redefinição porque o hardware está em um estado inválido ou porque o hardware é incapaz de redefinir os nós, o driver deve retornar uma falha status código. Se o agendador de GPU receber uma falha status código, ele executará uma operação de redefinição e reinicialização em todo o adaptador após o comportamento de TDR antes de Windows 8.

Mesmo que um driver tenha optado pelo comportamento de TDR Windows 8 e posterior, haverá casos em que o agendador de GPU solicita uma redefinição e reinicialização de todo o adaptador lógico. Portanto, o driver ainda deve implementar as funções DxgkDdiResetFromTimeout e DxgkDdiRestartFromTimeout e sua semântica permanece a mesma de antes de Windows 8. Quando uma tentativa de redefinir um adaptador físico com DxgkDdiResetEngine leva a uma redefinição do adaptador lógico, o comando !analyze do depurador do Windows mostra que o valor TdrReason do contexto de recuperação TDR está definido como um novo valor de TdrEngineTimeoutPromotedToAdapterReset = 9.