Fila de inversão de hardware

Este artigo descreve o recurso de fila de inversão de hardware com suporte a partir do Windows 11 (WDDM 3.0). O recurso de fila de inversão de hardware permite que vários quadros futuros sejam enviados para a fila do controlador de exibição. A CPU e as partes da GPU podem fazer a transição para estados de energia mais baixos enquanto o controlador de exibição está processando vários quadros enfileirados, melhorando a eficiência de energia de cenários de reprodução de vídeo em hardware compatível.

Modelo de fila de inversão pré-WDDM 3.0

Muitos controladores de exibição modernos dão suporte à capacidade de enfileirar vários quadros que devem ser exibidos em uma sequência. A partir do WDDM 2.1, o sistema operacional dá suporte a várias solicitações de substituição de inversão pendentes que devem ser apresentadas no próximo VSync. O KMD (driver de miniporta de exibição) indica esse suporte por meio do valor MaxQueuedMultiPlaneOverlayFlipVSync em DXGK_DRIVERCAPS. Essa funcionalidade é útil para reduzir a latência em cenários de jogos de alta taxa de quadros em que vários quadros são renderizados sequencialmente com o intervalo 0, com a intenção de exibir apenas o quadro mais recente.

Em cenários de reprodução de vídeo, o conteúdo de vários quadros futuros a serem exibidos sequencialmente é conhecido com antecedência e pode ser enfileirado para a GPU. Esse enfileiramento avançado permite que a CPU entre em um estado de baixa energia enquanto os quadros enfileirados são processados, resultando em uma economia substancial de energia. No entanto, antes do WDDM 3.0, não havia mecanismo para que o sistema operacional enviasse mais de um quadro que precisa permanecer na tela por pelo menos um intervalo VSync sem intervenção adicional da CPU. A seção Fila de inversão de hardware básica apresenta uma solução que permite que a CPU insira um estado de baixa energia e descarregue o processamento de quadro na fila para a GPU.

Em cenários de jogos anteriores ao WDDM 3.0, depois que a GPU termina de renderizar a cena para o buffer de fundo da cadeia de troca, há uma viagem de ida e volta para a CPU para enviar a solicitação para apresentar o conteúdo do quadro à tela. Para cargas de trabalho de GPU pesadas que terminam perto do VSync, essa viagem de ida e volta pode fazer com que os quadros sejam atrasados e percam o tempo de destino pretendido, resultando em falhas de quadro observáveis. A seção Fila avançada de inversão de hardware apresenta um mecanismo para evitar essa viagem de ida e volta da CPU e apresentar quadros concluídos na tela com latência muito baixa. A fila de inversão de hardware avançada requer a presença da fila de inversão de hardware básica e da funcionalidade do estágio 2 do agendamento de hardware da GPU.

Fila de inversão de hardware básica

O diagrama a seguir ilustra o caso de apresentar três quadros, cada um permanecendo na tela por um intervalo VSync.

Diagrama ilustrando três quadros permanecendo na tela para um intervalo VSync cada.

O padrão de preenchimento no diagrama mostra os momentos em que o processamento de fila de inversão de software Dxgkrnl e os threads de aplicativo precisam ser ativados e fazer o trabalho de CPU. Em cada VSync, o controlador de exibição precisa emitir uma notificação de CPU para o sistema operacional para a inversão concluída e o sistema operacional precisa enviar a próxima solicitação de inversão. O aplicativo também precisa ativar cada VSync e consultar estatísticas presentes para, eventualmente, saber quando o último quadro no lote de três é exibido.

Os DDIs da fila de inversão de hardware que podem enviar vários quadros futuros para a fila do controlador de exibição estão disponíveis a partir do WDDM 3.0. Conforme mencionado anteriormente, esse mecanismo permite que a CPU e partes da GPU façam a transição para estados de energia inferiores enquanto o controlador de vídeo está processando vários quadros enfileirados, melhorando a eficiência de energia de cenários de reprodução de vídeo em hardware compatível.

O diagrama a seguir ilustra a arquitetura proposta.

Diagrama que demonstra o mecanismo básico de fila de inversão de hardware.

Com a abordagem de fila de inversão de hardware, os componentes de CPU de aplicativo e Dxgkrnl ficam totalmente ociosos por dois intervalos VSync entre os tempos v2 e v4, permitindo que a CPU entre em um estado de baixa energia. A CPU só é notificada quando o quadro N+2 pelo qual o aplicativo solicitou uma espera é concluído.

Fila de inversão de hardware avançada

Em cenários de jogos antes do WDDM 3.0, depois que a GPU termina de renderizar a cena para o buffer de fundo da cadeia de troca, há uma viagem de ida e volta para a CPU para enviar a solicitação para apresentar o conteúdo do quadro à tela. O diagrama a seguir mostra esse cenário.

Diagrama ilustrando a conclusão do quadro que exige uma viagem de ida e volta da CPU.

O custo dessa viagem de ida e volta poderá fazer com que os quadros percam seu destino se a renderização for concluída muito perto do VSync, conforme mostrado no diagrama a seguir.

Diagrama ilustrando um quadro perdido devido à viagem de ida e volta da CPU necessária.

Alguns controladores de exibição dão suporte nativo a condições de espera que permitem que a exibição envie a solicitação de inversão depois que a GPU terminar de renderizar o quadro sem a viagem de ida e volta da CPU. Como a fila de inversão de hardware pode enviar o quadro N concluído para a exibição sem uma viagem de ida e volta da CPU, ela pode evitar quadros perdidos, conforme mostrado no diagrama a seguir.

Diagrama exibindo a conclusão do quadro sem a necessidade de uma viagem de ida e volta da CPU.

O restante deste artigo discute o recurso básico de fila de inversão de hardware.

Suporte a DDI

Os DDIs a seguir foram adicionados para dar suporte ao recurso de fila de inversão de hardware.

Verificando a disponibilidade do recurso

A fila de inversão de hardware requer a negociação habilitar/desabilitar o sistema operacional. Um KMD que dá suporte à fila de inversão de hardware deve primeiro chamar DXGKCB_QUERYFEATURESUPPORT durante a hora de início do dispositivo com uma FeatureId de DXGK_FEATURE_HWFLIPQUEUE para determinar se o sistema operacional permite que a fila de inversão de hardware seja habilitada.

A fila de inversão de hardware só poderá ser usada se o retorno de chamada for bem-sucedido e Habilitar estiver definido como TRUE.

Um KMD pode usar o código de exemplo a seguir durante o lançamento da fila de inversão de hardware e estágios experimentais.


DXGKARGCB_QUERYFEATURESUPPORT HwFlipQueueEnabledArgs = {};
HwFlipQueueEnabledArgs.DeviceHandle = DeviceHandle;
HwFlipQueueEnabledArgs.FeatureId = DXGK_FEATURE_HWFLIPQUEUE;
HwFlipQueueEnabledArgs.DriverSupportState = DXGK_FEATURE_SUPPORT_EXPERIMENTAL;

if (!NT_SUCCESS(pDxgkInterface->DxgkCbQueryFeatureSupport(&HwFlipQueueEnabledArgs)) ||
    !HwFlipQueueEnabledArgs.Enabled)
{
    // Disable hardware flip queue because the OS didn't allow it.           
}
else
{
    // Enable hardware flip queue because the OS allowed it.
}

Durante a ativação do driver, embora seja possível habilitar a fila de inversão de hardware sem habilitar o agendamento de hardware de GPU, essa combinação não tem suporte oficial. Atualmente, o Windows exige que o agendamento de hardware de GPU seja habilitado para que a fila de inversão de hardware básica seja habilitada em drivers lançados oficialmente.

Indicando recursos de enfileiramento de hardware

MaxHwQueuedFlips foi adicionado ao DXGK_DRIVERCAPS para indicar o suporte à fila de inversão de hardware. Se o sistema operacional permitiu suporte à fila de inversão de hardware conforme descrito anteriormente, um KMD que dá suporte à fila de inversão de hardware deve definir MaxHwQueuedFlips como um valor maior que 1. Quando MaxHwQueuedFlips é maior que 1, KMD indica que o hardware de exibição dá suporte a até quadros futuros MaxHwQueuedFlips que podem ser enfileirados para serem exibidos para um determinado VidPnSource na GPU. O sistema operacional respeitará as restrições fornecidas pelo driver sobre o tipo de inversão que pode ser enfileirada com antecedência.

HwQueuedFlipCaps também foi adicionado ao DXGK_DRIVERCAPS. No momento, esse membro está reservado para uso do sistema e não deve ser usado por drivers.

Inverter o formato de carimbo de data/hora de destino e hora de destino

Quando o sistema operacional envia uma solicitação de inversão para a fila de inversão de hardware, ele também envia o tempo de inversão de destino. A inversão pode ficar visível para o usuário depois que o tempo de inversão de destino for atingido.

O sistema operacional usa as unidades de contador do relógio da CPU, obtidas de KeQueryPerformanceCounter, para passar o tempo de quadro de destino e interpretar o tempo de quadro real.

Enviando inversãos enfileiradas

A estrutura DXGKARG_SETVIDPNSOURCEADDRESSWITHMULTIPLANEOVERLAY3 , que é passada para a função de retorno de chamada DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 do KMD, foi modificada da seguinte maneira para habilitar o envio de inversãos enfileiradas:

  • Os três membros a seguir foram adicionados à estrutura DXGK_SETVIDPNSOURCEADDRESS_OUTPUT_FLAGS de OutputFlags. Consulte Casos de repetição e falha de DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 para obter detalhes sobre esses membros.

    • HwFlipQueueDrainNeeded
    • HwFlipQueueDrainAllPlanes
    • HwFlipQueueDrainAllSources
  • Um membro TargetFlipTime foi adicionado. TargetFlipTime descreve o tempo de inversão de destino em unidades QPC. Quando o relógio atinge esse valor, o quadro pode ser enviado para a exibição, respeitando vSync e rasgando sinalizadores. Na presença de inversãos pendentes anteriormente enfileiradas, o sistema operacional garante que, para cada plano MPO referenciado pela solicitação de inversão, TargetFlipTime seja maior ou igual a qualquer um dos tempos de destino de inversão pendentes para este plano. Em outras palavras, pode haver uma sequência de inversãos com os mesmos carimbos de data/hora ou aumento, mas não pode haver uma sequência que volte no tempo.

DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 casos de repetição e falha

Falha ao enfileirar a solicitação para hardware devido a inversãos pendentes

Há vários casos especiais que podem impedir o KMD de enfileirar uma solicitação de inversão enquanto outras solicitações de inversão estão pendentes. Nesses casos, o KMD deve retornar STATUS_RETRY de DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 e definir HwFlipQueueDrainNeeded igual a 1. O sistema operacional tentará enviar a solicitação de inversão novamente depois que todas as inversãos pendentes em planos afetados por essa inversão forem concluídas e quando o tempo de destino for atingido.

Em alguns casos, o hardware de exibição pode exigir a conclusão de inversãos pendentes em todos os planos, não apenas os referenciados pela solicitação de inversão de entrada. Nesse caso, os sinalizadores HwFlipQueueDrainNeeded e HwFlipQueueDrainAllPlanes devem ser definidos como 1, e o KMD deve retornar STATUS_RETRY.

Da mesma forma, o hardware de exibição pode exigir a conclusão de inversãos pendentes em todas as fontes VidPn para realocar recursos internos; nesse caso, os sinalizadores HwFlipQueueDrainAllSources e HwFlipQueueDrainNeeded devem ser definidos e o KMD deve retornar STATUS_RETRY.

Além disso, o KMD pode indicar ao sistema operacional se a reenviação deve ser feita no IRQL do dispositivo (PrePresentNeeded definido como 0) ou se o sistema operacional deve executar essa chamada em PASSIVE_LEVEL (PrePresentNeeded definido como 1). Se o KMD ainda retornar STATUS_RETRY mesmo que não haja mais inversões pendentes nesse VidPnSourceId, essa condição será tratada como uma falha de parâmetro inválida.

É importante que o valor de MaxHwQueuedFlips ainda reflita o número máximo de inversões de alteração somente de endereço simples que podem ser enfileiradas em um plano MPO. O mecanismo de STATUS_RETRY deve ser usado para solicitações de inversão mais complexas que não podem ser profundamente enfileiradas, como alterações de configuração de plano.

Falha de parâmetro inválida

No modelo de fila de inversão de hardware, o tratamento do sistema operacional de solicitações de inversão com falha foi retrabalhado para permitir uma melhor depuração. Quando o KMD não consegue processar uma solicitação de inversão, ele deve retornar STATUS_INVALID_PARAMETER de DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3. Dependendo das configurações do sistema operacional, o sistema operacional executará uma das seguintes ações:

  • Interrupção do depurador de kernel e marcar de bugs: esse comportamento geralmente será habilitado em builds de desenvolvimento/pré-lançamento para melhor depuração à medida que a condição de falha ocorrer.
  • Despejo de kernel dinâmico seguido por um TDR: o comportamento do usuário final de varejo.

Especificando o comportamento de interrupção do VSync

Para obter economia de energia em cenários de inversão na fila, o sistema operacional geralmente suspenderá interrupções regulares do VSync para manter a CPU em um estado de baixa energia. No entanto, algumas inversãos serão marcadas como exigindo que uma interrupção seja gerada para que o aplicativo observe o lote de presentes concluídos e para enfileirar trabalhos adicionais. Também há casos em que os aplicativos solicitam ativação em cada interrupção do VSync, independentemente de haver solicitações de inversão pendentes. Por outro lado, em um sistema completamente ocioso, as interrupções do VSync são suspensas até que novas atividades de apresentação ou ouvintes VSync apareçam.

Para lidar com todos esses casos, o seguinte retorno de chamada de driver e estrutura de retorno de chamada foram introduzidos:

O KMD fornece um ponteiro para sua função DxgkDdiSetInterruptTargetPresentId no DRIVER_INITIALIZATION_DATA

O sistema operacional chama DxgkDdiSetInterruptTargetPresentId para especificar o PresentId de destino que deve resultar em uma interrupção VSync gerada quando a inversão correspondente for concluída. Ele é chamado no nível de interrupção do dispositivo (DIRQL) para sincronizar com DxgkDdiSetVidPnSourceAddress e a interrupção VSync.

Interação com DxgkDdiControlInterrupt

Quando as interrupções VSync são desabilitadas inteiramente por meio de DxgkDdiControlInterrupt/DxgkDdiControlInterrupt2/DxgkDdiControlInterrupt3, elas permanecem desabilitadas independentemente do valor PresentId de destino de interrupção. O KMD é necessário para armazenar a ID atual de destino de interrupção mais recente para que ela possa ser respeitada quando o VSync for habilitado novamente.

Quando as interrupções VSync são habilitadas por meio de DxgkDdiControlInterruptXxx, a ID presente de destino de interrupção (pSetInterruptTargetPresentId) fornece um controle refinado da seguinte maneira:

  • Quando a ID presente de destino é definida como UINT64_MAX, nenhuma interrupção VSync é necessária daqui para frente até que a ID atual de destino seja alterada novamente. As interrupções VSync estão desabilitadas, mas o KMD é necessário para implementar DXGK_VSYNC_DISABLE_KEEP_PHASE comportamento para reabilitar interrupções.

  • Quando a ID presente de destino é definida como 0, as interrupções são necessárias para cada VSync.

  • Para qualquer outro valor de ID atual, as interrupções serão geradas se o PresentId >atualmente verificado = InterruptTargetPresentId.

Quando vários planos de MPO estiverem disponíveis, a interrupção VSync deverá ser gerada se algum dos planos exigir isso.

2 estágios VSync desabilitar com DxgkDdiSetInterruptTargetPresentId

Se a chamada do sistema operacional para DxgkDdiSetInterruptTargetPresentId definir um InterruptTargetPresentId em um plano que levaria a desabilitar totalmente o VSync neste VidPnSource (ou seja, esse plano foi o último plano que manteve o VSync habilitado e agora está desabilitando o VSync também), o KMD deve desabilitar as interrupções VSync, mas manter a fase VSync no hardware habilitada (DXGK_VSYNC_DISABLE_KEEP_PHASE). Após um determinado período de tempo (normalmente equivalente a dois períodos VSync), o sistema operacional seguirá com uma chamada para DxgkDdiControlInterruptXxx com DXGK_VSYNC_DISABLE_NO_PHASE. Essa chamada garante que o KMD tenha a chance de desabilitar a fase VSync e os relógios VSync para economizar energia máxima e manter a paridade de desempenho com sistemas de fila de inversão de hardware.

Cancelamento de inversão na fila

Em casos como transições de estado em tela inteira ou saídas de aplicativos, versões futuras enfileiradas podem precisar ser canceladas. Para lidar com esses casos, o seguinte retorno de chamada de driver e estruturas relacionadas foram introduzidos:

O KMD fornece um ponteiro para sua função DxgkDdiCancelFlips em DRIVER_INITIALIZATION_DATA.

O sistema operacional especifica o intervalo de inversãos enfileiradas a serem canceladas quando chama DxgkDdiCancelFlips, e o KMD relata de volta ao sistema operacional o intervalo de inversões que foi capaz de cancelar de forma síncrona.

O exemplo a seguir ilustra a mecânica e o caso síncrono de cancelamento de inversão em um único plano. (O sistema operacional não dá suporte ao cancelamento assíncrono no Windows 11, versão 22H2.) Imagine que as seguintes versões estão sendo enfileiradas na fila de inversão de hardware:

  • PresentId N
  • time t0 PresentId N+1
  • time t1 PresentId N+2
  • time t2 PresentId N+3
  • time t3 PresentId N+4
  • time t4

Em seguida, o sistema operacional decide cancelar os lançamentos N+2, N+3 e N+4, portanto, ele chama DxgkDdiCancelFlips com PresentIdCancelRequested definido comoN+2.

Quando o KMD inspeciona o estado da fila de inversão de hardware, ele determinou que o flip N+2 já foi enviado para o hardware de exibição e não pode ser cancelado no momento da chamada, mas N+3 e N+4 podem ser removidos de forma síncrona da fila de inversão de hardware sem efeitos colaterais. O KMD define PresentIdCancelled como N+3 e conclui N+2 como de costume.

O sistema operacional marcará N+3 e N+4 como cancelados e tratará N, N+1, N+2 como sendo em voo. Quando as próximas interrupções VSync forem geradas, o log da fila de inversão indicará os carimbos de data/hora para N, N+1, N+2 , como de costume.

O intervalo de inversãos canceladas de forma síncrona deve ser contínuo e, quando não é zero, é considerado incluir a última ID atual enviada ao KMD. Em outras palavras, não pode haver lacunas dentro de ambos os intervalos de inversão cancelados síncronos.

Cancelando inversãos interligadas em vários planos

Uma inversão intertravada é enviada chamando DxgkDdiSetVidPnSourceAddress com vários planos e PresentIds. O contrato entre o sistema operacional e o KMD segue:

  • O conjunto de planos deve ficar visível no mesmo VSync.
  • O hardware de exibição não tem permissão para exibir apenas um subconjunto desses planos em um VSync e o restante no próximo VSync.

No modelo de fila de inversão de hardware, esses flips interlocked são cancelados passando vários planos e PresentIds na chamada para DxgkDdiCancelFlips. O conjunto de planos passados nesses casos deve corresponder a uma solicitação de inversão intertravada pendente, e a decisão do KMD sobre todas as PresentIds interlocked deve ser a mesma:

  • Não cancele ou
  • Cancelar de forma síncrona

DxgkDdiCancelFlips é chamado no nível de interrupção do dispositivo (DIRQL) para sincronizar com DxgkDdiSetVidPnSourceAddress e interrupção VSync.

Obtendo estatísticas atuais para versões invertidas na fila

Como a abordagem da fila de inversão de hardware é evitar acordar a CPU em cada VSync, é necessário haver um mecanismo para manter os tempos de exibição de quadro para as últimas várias versões na fila.

Os drivers gráficos que dão suporte à fila de inversão de hardware são necessários para gravar informações para cada inversão concluída ou cancelada por um determinado plano de MPO para cada VidPnSource ativo no buffer de log de fila de inversão fornecido pelo sistema operacional.

O sistema operacional garante fornecer o ponteiro de log de fila de inversão (em uma chamada para DxgkDdiSetFlipQueueLogBuffer) antes da primeira chamada DxgkDdiSetVidPnSourceAddress para um determinado plano MPO para cada VidPnSource ativo. O sistema operacional tem permissão para destruir o buffer de log de fila de inversão quando a fila de inversão não tiver nenhuma solicitação pendente. Nesse caso, ele fornecerá um novo ponteiro de log antes da próxima chamada DxgkDdiSetVidPnSourceAddress . O log da fila de inversão é circular. Depois que a entrada [NumberOfEntries-1] for gravada, a próxima entrada de log será [0].

Depois que um lote de invertidos enfileirados for concluído, o KMD precisará garantir que o log de filas de inversão para as versões concluídas seja atualizado no início desses dois pontos no tempo:

  • Um manipulador de interrupção VSync para uma inversão que exigia que uma interrupção fosse gerada.
  • Em resposta a uma solicitação DxgkDdiUpdateFlipQueueLog explícita do sistema operacional.

Inverter DDIs de log de fila

O seguinte retorno de chamada relacionado ao log de inversão de fila e estruturas associadas foram adicionados:

O KMD fornece um ponteiro para suas funções em DRIVER_INITIALIZATION_DATA.

Atualizações de estrutura de interrupção VSync

As seguintes alterações foram feitas na estrutura DXGKARGCB_NOTIFY_INTERRUPT_DATA para implementar interrupções VSync para o modelo de fila de inversão de hardware:

  • O valor de enumeração DXGK_INTERRUPT_CRTC_VSYNC_WITH_MULTIPLANE_OVERLAY3 foi adicionado como InterruptType.
  • A estrutura CrtcVSyncWithMultiPlaneOverlay3 foi adicionada à união. A semântica de CrtcVSyncWithMultiPlaneOverlay3 é semelhante à estrutura crtcVSyncWithMultiPlaneOverlay2 existente, exceto que, em vez de um único PresentId concluído pela última vez para cada plano, CrtcVSyncWithMultiPlaneOverlay3.pMultiPlaneOverlayVSyncInfo aponta para o intervalo de PresentIds não relatados anteriormente do log da fila de inversão.
  • A estrutura DXGK_MULTIPLANE_OVERLAY_VSYNC_INFO3 foi adicionada para o membro pMultiPlaneOverlay3 de CrtcVSyncWithMultiPlaneOverlay3.

Usando o diagrama de exemplo básico de fila de inversão de hardware novamente:

Diagrama demonstrando o mecanismo básico de fila de inversão de hardware.

Suponha que FirstFreeFlipQueueLogEntryIndex foi definido como 40 no momento em que o flip N foi enviado e, em seguida, N, N+1, N+2 presentes foram concluídos.

Depois que uma configuração de plano único concluir três PresentIds N, N+1 e N+2 nos respectivos horários v2, v3, v4, KMD terá gravado três novas entradas em seu buffer de log de fila de inversão com índices 40, 41 e 42. O KMD relata um valor FirstFreeFlipQueueLogEntryIndex de 43 na estrutura CrtcVSyncWithMultiPlaneOverlay3 . O sistema operacional observará que FirstFreeFlipQueueLogEntryIndex foi alterado de 40 para 43 e lerá as entradas de log 40, 41 e 42. O KMD precisa definir os seguintes valores de buffer de log de fila de inversão da seguinte maneira:

  • VidPnTargetId: mesmo significado que em CrtcVSyncWithMultiPlaneOverlay2

  • PhysicalAdapterMask: mesmo significado que em CrtcVSyncWithMultiPlaneOverlay2

  • MultiPlaneOverlayVSyncInfoCount = 1

  • pMultiPlaneOverlayVSyncInfo[0]. LayerIndex = 0

  • pMultiPlaneOverlayVSyncInfo[0]. FirstFreeFlipQueueLogEntryIndex = 43

  • LogBufferAddressForPlane0[40]. PresentId = N

  • LogBufferAddressForPlane0[40]. PresentTimestamp = v2

  • LogBufferAddressForPlane0[41]. PresentId = N+1

  • LogBufferAddressForPlane0[41]. PresentTimestamp = v3

  • LogBufferAddressForPlane0[42]. PresentId = N+2

  • LogBufferAddressForPlane0[42]. PresentTimestamp = v4

Solicitação explícita de atualização de log de fila de inversão

Há casos em que o sistema operacional precisa obter informações sobre o último lote concluído de inversãos sem precisar aguardar a interrupção do VSync. Nesses casos, o sistema operacional faz uma chamada explícita para DxgkDdiUpdateFlipQueueLog para solicitar que o KMD leia de sua estrutura de dados de hardware de exibição proprietária e grave informações de inversão passadas no log da fila de inversão. A semântica do log é a mesma descrita anteriormente; a única alteração é que FirstFreeFlipQueueLogEntryIndex é retornado ao sistema operacional fora da interrupção VSync.

DxgkDdiUpdateFlipQueueLog é chamado no nível de interrupção do dispositivo (DIRQL) e está na mesma classe de sincronização que DDI DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 .

Alterações no modo de exibição e transições de energia na presença de uma inversão na fila de inversão de hardware

O Dxgkrnl garantirá que as inversões já enfileiradas na fila de inversão de hardware sejam concluídas ou canceladas antes de iniciar uma alteração de modo ou desligar o monitor.

Mapeamento Apresentar solicitações para carimbos de data/hora da fila de inversão de hardware

Quando a fila de inversão de hardware estiver habilitada em um adaptador específico, todas as chamadas de inversão serão acompanhadas por um carimbo de data/hora. Em outras palavras, o KMD não precisará lidar com uma combinação de semântica DxgkDdiSetVidPnSourceAddress antiga e nova.

O sistema operacional converterá automaticamente as solicitações de API Presente baseadas em intervalo existentes em chamadas invertidas baseadas em carimbo de data/hora para KMD. As seções a seguir discutem vários casos e como eles são mapeados para uma combinação de sinalizadores, Duração e carimbos de data/hora recebidos pelo KMD.

Rasgar e não rasgar inverte semântica

A semântica de lançamentos de tearing é conceitualmente a mesma quando a fila de inversão de hardware está habilitada. Depois que o TargetFlipTime for atingido, o KMD deverá enviar a inversão para exibição enquanto ainda honra sinalizadores como FlipImmediate, FlipImmediateNoTearing e FlipOnNextVSync. Em outras palavras, o KMD deve se comportar como se o sistema operacional enviasse a inversão para ele exatamente em TargetFlipTime com os mesmos sinalizadores e parâmetros de inversão.

Por exemplo, se FlipOnNextVSync estiver definido como 1 e TargetFlipTime estiver no meio do quadro, essa inversão só deverá ser exibida no próximo VSync.

FlipOverwrite suporte e fila de inversão de hardware

A fila de inversão de hardware é um superconjunto estrito do recurso de substituição de inversão controlado pelo valor MaxQueuedMultiPlaneOverlayFlipVSync em DXGK_DRIVERCAPS.

Portanto, o sistema operacional ignorará o valor MaxQueuedMultiPlaneOverlayFlipVSync se o driver optar pela fila de inversão de hardware definindo MaxHwQueuedFlips como um valor maior que 1.

Várias versões com um TargetFlipTime expirado

Quando há várias inversãos na fila com um TargetFlipTime expirado para um determinado plano MPO, a fila de exibição de hardware deve escolher a inversão expirada na fila mais recente e enviá-la para exibição. O restante das versões expiradas deve ser tratado como cancelado e as entradas de log de fila de inversão correspondentes para elas devem conter DXGK_HWFLIPQUEUE_TIMESTAMP_CANCELLED como os valores PresentTimestamp .

Interação entre Duration e TargetFlipTime

O parâmetro Duration na estrutura DXGKARG_SETVIDPNSOURCEADDRESSWITHMULTIPLANEOVERLAY3 deve entrar em vigor quando a inversão especificada nessa estrutura for exibida na tela. Ele especifica o novo comportamento de taxa de atualização de exibição desejado para a saída especificada por VidPnSourceId em todos os planos. Nas versões WDDM 3.1 e Windows 2022, para simplificar a implementação do driver para hardware que não dá suporte a alterações de duração personalizadas na fila, o sistema operacional só envia solicitações de inversão com um novo parâmetro Duration após a conclusão das solicitações de inversão anteriores.

Mapeando intervalos presentes para TargetFlipTime

Intervalos de mapeamento quando a taxa de atualização é fixa

Para preservar a semântica de intervalo atual existente, o sistema operacional precisa calcular o tempo de inversão de destino usando o intervalo atual e a taxa de atualização. No entanto, definir o tempo de inversão de destino exatamente para o tempo de VSync pretendido no qual a inversão deve atingir a tela resultará em falhas frequentes devido ao VSync perdido caso o tempo real de VSync desça um pouco. Para se proteger contra falhas, o sistema operacional subtrai metade do intervalo VSync do tempo de inversão de destino calculado.

Aqui está uma fórmula simplificada para mapear o intervalo atual para o tempo de inversão de destino:

TargetFlipTime = PreviousFlipStartVSyncTime + (PreviousFlipPresentInterval * FixedRefreshRate) - (FixedRefreshRate / 2)

Intervalos de mapeamento quando o recurso WDDM 2.9 da taxa de atualização virtual está presente

O recurso de taxa de atualização virtual pode aumentar temporariamente a taxa de atualização de exibição para um número inteiro múltiplo da taxa de atualização atual (ou seja, 24 Hz podem ser aumentados para 144 Hz ou 192 Hz). Para dispositivos capazes de dar suporte a esse aumento, a fórmula na seção anterior é modificada para usar o múltiplo mais rápido da taxa de atualização atual:

TargetFlipTime = PreviousFlipStartVSyncTime + (PreviousFlipPresentInterval * FixedRefreshRate) - (FastestRefreshRate / 2)

Intervalos de mapeamento quando a taxa de atualização é alterada para um não múltiplo

Quando a taxa de atualização for alterada para um não múltiplo de uma taxa de atualização atual (por exemplo, de 24 Hz para 60 Hz), o sistema operacional terá que inspecionar as inversões da fila para ver se o tempo de destino calculado ainda é válido dada a nova taxa de atualização. Se o tempo de inversão de destino precisar ser alterado, o sistema operacional cancelará as inversões enfileiradas e as redirecionará com os tempos de inversão de destino calculados recentemente.