Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo descreve o recurso de fila de hardware invertida que é compatível a partir do Windows 11 (WDDM 3.0). Uma 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 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 energética em cenários de reprodução de vídeo em hardware compatível.
Modelo de fila de troca 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 pendentes de sobreposição de frames que devem ser apresentadas no próximo VSync. O driver de miniport de display (KMD) 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 na GPU. Esse enfileiramento avançado permite que a CPU entre em um estado de baixa potência enquanto os quadros enfileirados são processados, resultando em uma economia significativa de energia. No entanto, antes do WDDM 3.0, não havia mecanismo para que o sistema operacional enviasse mais de um quadro que precisasse permanecer na tela por pelo menos um intervalo VSync sem intervenção adicional da CPU. A seção fila de alternância de hardware básico apresenta uma solução que permite que a CPU entre em um estado de baixa potência e descarregue o processamento de quadros em fila para a GPU.
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á um processo de ida e volta para a CPU a fim de enviar a solicitação para apresentar o conteúdo do quadro na 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 de Inversão de Hardware Avançado apresenta um mecanismo para evitar esse "roundtrip" da CPU e apresentar quadros concluídos na tela com baixa latência. A fila de inversão de hardware avançada requer que estejam presentes tanto a funcionalidade básica de fila de inversão de hardware quanto a funcionalidade de agendamento de hardware da GPU estágio 2.
Fila básica de troca de hardware
O diagrama a seguir ilustra o caso de apresentar três quadros, cada um permanecendo na tela para um intervalo VSync.
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 do aplicativo precisam acordar e executar tarefas na 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, aprender quando o último quadro no lote de três é exibido.
DDIs de 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. Como indicado anteriormente, esse mecanismo permite que a CPU e partes da GPU sejam transferidas para estados de energia mais baixos enquanto o controlador de exibição está processando vários quadros na fila. Essa transição melhora a eficiência de energia dos cenários de reprodução de vídeo em hardware capaz.
O diagrama a seguir ilustra a arquitetura proposta.
Com a abordagem da fila de inversão de hardware, os componentes de CPU do aplicativo e Dxgkrnl ficam totalmente ociosos por dois intervalos VSync entre os tempos v2 e v4, permitindo que a CPU insira um estado de baixa potência. A CPU só é notificada quando o quadro N+2, para o qual o aplicativo solicitou uma espera, é concluído.
Fila de troca 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á um processo de ida e volta para a CPU a fim de enviar a solicitação para apresentar o conteúdo do quadro na tela. O diagrama a seguir mostra esse cenário.
O custo dessa viagem de ida e volta pode fazer com que os quadros percam o destino se a renderização for concluída muito perto do VSync, conforme mostrado no diagrama a seguir.
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 tela sem uma passagem pela CPU, ela pode evitar quadros perdidos, conforme mostrado no diagrama a seguir.
O restante deste artigo discute o recurso básico de fila de inversão de hardware.
Suporte à 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 de habilitação/desabilitação do sistema operacional. Um KMD que dá suporte à fila de inversão de hardware deve primeiro chamar DXGKCB_QUERYFEATURESUPPORT durante o início do dispositivo, com um 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 for definido como TRUE.
Um KMD pode usar o código de exemplo a seguir durante a inicialização da fila flip 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 configuração do driver, embora seja possível habilitar a fila de transferência de hardware sem habilitar o agendamento de hardware da GPU, essa combinação não é oficialmente suportada. 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 capacidades 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 a uma fila de inversão de hardware deverá 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é MaxHwQueuedFlips quadros futuros que podem ser colocados na fila para serem exibidos para um determinado VidPnSource na GPU. O sistema operacional respeita as restrições fornecidas pelo driver sobre o tipo de inversões que podem ser enfileiradas com antecedência.
HwQueuedFlipCaps também foi adicionado ao DXGK_DRIVERCAPS. Este membro está atualmente reservado para uso do sistema; os controladores não devem usá-lo.
Inverter o formato de carimbo de data/hora de destino e de hora-alvo.
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 se tornar visível para o usuário após atingir o tempo de inversão desejado.
O sistema operacional usa as unidades de contador de relógio da CPU, obtidas de KeQueryPerformanceCounter, para transmitir o tempo de quadro alvo e interpretar o tempo real do quadro.
Enviando flips na fila
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ões na fila:
Os três membros a seguir foram adicionados à estrutura de DXGK_SETVIDPNSOURCEADDRESS_OUTPUT_FLAGS do OutputFlags. Veja casos de tentativa e falha DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 para obter detalhes sobre esses membros.
- HwFlipQueueDrainNeeded
- HwFlipQueueDrainAllPlanes
- HwFlipQueueDrainAllSources
Um membro TargetFlipTime foi adicionado. TargetFlipTime descreve o tempo previsto de inversão em unidades QPC. Quando o relógio atinge esse valor, o quadro pode ser enviado para a tela, respeitando os indicadores de VSync e tearing. Na presença de flips pendentes previamente encadeados, o sistema operacional garante que, para cada plano MPO referenciado pela solicitação de flip, TargetFlipTime seja maior ou igual a qualquer um dos horários-alvo de flip pendentes para este plano. Em outras palavras, pode haver uma sequência de mudanças com carimbos de data/hora iguais ou em ordem crescente, mas não pode haver uma sequência que retroceda no tempo.
Casos de repetição e falhas DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3
Falha ao enfileirar a solicitação para hardware devido a versões 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, KMD deve retornar STATUS_RETRY de DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 e definir que HwFlipQueueDrainNeeded seja igual a 1. O sistema operacional tentará enviar a solicitação de inversão novamente após todas as operações pendentes nos componentes afetados pela inversão serem concluídas e quando o tempo alvo for atingido.
Em alguns casos, o hardware de exibição pode exigir a conclusão de inversões 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ões 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 simples alterações apenas de endereço 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 gerenciamento de inversão de hardware, o sistema operacional passou a lidar melhor com solicitações de inversão falhadas, permitindo uma depuração mais eficaz. 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 executa uma das seguintes ações:
- Parada e verificação de bugs do Depurador do Kernel: esse comportamento geralmente é habilitado em versões de desenvolvimento/pré-lançamento para melhor depuração assim que a condição de falha ocorre.
- Despejo de Kernel Ao Vivo seguido por um TDR: o comportamento do usuário final do varejo.
Especificando o comportamento de interrupção VSync
Para economizar energia em cenários de reversão em fila, o sistema operacional geralmente suspende interrupções regulares de VSync para manter a CPU em um estado de baixa potência. No entanto, algumas trocas são marcadas como exigindo que uma interrupção seja ativada para que o aplicativo observe o lote de apresentações concluídas e enfileire mais tarefas. Há também casos em que os aplicativos solicitam a ativação em cada interrupção VSync, independentemente de haver solicitações de inversão pendentes. Por outro lado, em um sistema completamente ocioso, as interrupções VSync são suspensas até que novas atividades de apresentação sejam iniciadas ou que ouvintes VSync surjam.
Para lidar com todos esses casos, as seguintes estruturas foram introduzidas: retorno de chamada do driver e estrutura de retorno de chamada.
O KMD fornece um ponteiro para sua função DxgkDdiSetInterruptTargetPresentId em DRIVER_INITIALIZATION_DATA
O sistema operacional chama DxgkDdiSetInterruptTargetPresentId para especificar o PresentId de destino que deve ativar uma interrupção de VSync quando a troca correspondente for concluída. Essa função é chamada 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 do destino de interrupção mais recente para que ela possa ser respeitada quando o VSync estiver habilitado novamente.
Quando as interrupções VSync são habilitadas por meio de DxgkDdiControlInterruptXxx, o ID do alvo de interrupção presente (pSetInterruptTargetPresentId) fornece um controle mais detalhado da seguinte maneira:
Quando a ID atual 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 é necessário que o KMD implemente o comportamento DXGK_VSYNC_DISABLE_KEEP_PHASE para reabilitar interrupções.
Quando a ID de destino atual é definida como 0, interrupções tornam-se obrigatórias para cada VSync.
Para qualquer outro valor de ID presente, interrupções são geradas se o PresentId atualmente escaneado > = InterruptTargetPresentId.
Quando vários planos MPO estiverem disponíveis, a interrupção de VSync deverá ser gerada se algum dos planos necessitar disso.
Desativação em 2 etapas do VSync com DxgkDdiSetInterruptTargetPresentId
Se a chamada do sistema operacional para DxgkDdiSetInterruptTargetPresentId definir um InterruptTargetPresentId em um plano que levaria a desativar completamente o VSync neste VidPnSource (ou seja, se este plano for o último que mantinha o VSync ativo e estiver agora desativando-o), o KMD deve desativar as interrupções de VSync, mas manter a fase de 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 de VSync e os relógios de VSync para economizar o máximo de energia e manter a paridade de desempenho com sistemas de fila flip que não utilizam hardware.
Cancelamento de inversão na fila
Em casos como transições de estado de tela inteira ou saídas de aplicativo, 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ões 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 do cancelamento de flip em um único plano. (O sistema operacional não dá suporte a cancelamento assíncrono no Windows 11, versão 22H2.) Imagine que as seguintes versões estão sendo enfileiradas na fila de lançamento de hardware:
- PresentId N
- time t0 PresentId N+1
- time t1 PresentId N+2
- time t2 PresentId N+3
- time t3 PresentId N+4
- tempo t4
Em seguida, o sistema operacional decide cancelar as intercalações N+2, N+3 e N+4, então ele chama DxgkDdiCancelFlips com PresentIdCancelRequested definido como N+2.
Quando o KMD inspeciona o estado da fila de inversão de hardware, ele determina que:
- O Flip N+2 já é enviado para o hardware de exibição e não pode ser cancelado no momento da chamada.
- Os flips N+3 e N+4 podem ser removidos de forma síncrona da fila de flips de hardware sem efeitos colaterais.
Como resultado, o KMD define PresentIdCancelled como N+3 e conclui N+2 como de costume.
O sistema operacional marca N+3 e N+4 como cancelados e trata N, N+1, N+2 como sendo em voo. Quando as próximas interrupções de VSync forem geradas, o registro da fila de inversão indicará os carimbos de data/hora para N, N+1, N+2 como de costume.
O intervalo de inversões canceladas sincronamente deve ser contínuo e, quando não for zero, presume-se que inclua a última ID enviada ao KMD. Em outras palavras, não pode haver lacunas dentro de ambos os intervalos de inversões cancelados síncronos.
Cancelando giros intertravados em múltiplos planos
Uma inversão intertravada é realizada ao chamar DxgkDdiSetVidPnSourceAddress contendo diversos planos e PresentIds. O contrato entre o sistema operacional e o KMD segue:
- O conjunto de planos deve ser exibido no mesmo VSync.
- Não é permitido ao hardware de exibição mostrar apenas um subconjunto desses planos em um VSync e o restante no próximo VSync.
No modelo de fila de espera de inversão de hardware, essas inversões intertravadas são canceladas ao passar vários planos e PresentIds na chamada para DxgkDdiCancelFlips. O conjunto de planos apresentados nesses casos deve corresponder a uma solicitação pendente de inversão intertravada, e a decisão do KMD sobre todas as PresentIds intertravadas deve ser a mesma.
- Não cancele, ou ... (additional context needed)
- 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 flips 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 vários dos últimos flips na fila.
Os drivers gráficos que dão suporte à fila de inversão de hardware devem gravar informações no buffer de log de fila de inversão fornecido pelo sistema operacional para cada inversão concluída ou cancelada para um determinado plano MPO para cada VidPnSource ativo.
O sistema operacional garante fornecer o ponteiro de log da fila de reversão (em uma chamada para DxgkDdiSetFlipQueueLogBuffer) antes da primeira chamada de DxgkDdiSetVidPnSourceAddress para um plano MPO específico de cada VidPnSource ativo. O sistema operacional tem permissão para destruir o buffer de log da 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].
Após a conclusão de um lote de inversões na fila, o KMD precisa garantir que o log da fila de inversões para os lançamentos concluídos seja atualizado no ponto mais cedo entre esses dois momentos no tempo.
- Um manipulador de interrupção VSync para um inverso 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
As seguintes estruturas e retornos de chamada relacionados ao log de fila de inversão foram adicionados:
O KMD fornece um ponteiro para suas funções em DRIVER_INITIALIZATION_DATA.
Atualizações da 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 troca 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 de dados. 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 flip.
- A estrutura DXGK_MULTIPLANE_OVERLAY_VSYNC_INFO3 foi adicionada para o membro CrtcVSyncWithMultiPlaneOverlay3pMultiPlaneOverlayVSyncInfo.
Usando novamente o diagrama de exemplo de fila de inversão de hardware básico:
Suponha que FirstFreeFlipQueueLogEntryIndex foi definido como 40 no momento em que o flip N foi enviado e que, em seguida, as apresentações N, N+1, N+2 foram concluídas.
Após a conclusão de uma configuração de plano único que completa três PresentIds N, N+1 e N+2 nos respectivos horários v2, v3, v4, o KMD gravou 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 observa que FirstFreeFlipQueueLogEntryIndex foi alterado de 40 para 43 e lê das 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 de atualização de log de fila de inversão explícita
Há casos em que o sistema operacional precisa obter informações sobre o último lote concluído de inversões 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 escreva 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 para o 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 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 DDI.
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
Dxgkrnl garante que os flips já enfileirados na fila de flip de hardware sejam concluídos ou cancelados antes de iniciar uma alteração de modo ou desligar o monitor.
Mapeando as solicitações "Present" para carimbos de data/hora da fila de comutação de hardware
Quando a fila de reversão de hardware está habilitada em um adaptador específico, um timestamp acompanha todas as chamadas de reversão. Em outras palavras, KMD não precisa lidar com uma mistura de semântica DxgkDdiSetVidPnSourceAddress antiga e nova.
O sistema operacional converte automaticamente solicitações de API Presente baseadas em intervalo existentes em chamadas de inversão 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, Duration e timestamps recebidos pelo KMD.
Rasgar e nontear vira semântica
A semântica das inversões de tearing é conceitualmente a mesma quando a fila de exibição de hardware está habilitada. Depois que o TargetFlipTime for atingido, o KMD deverá enviar o flip para exibição enquanto ainda estiver respeitando sinalizadores como FlipImmediate, FlipImmediateNoTearing e FlipOnNextVSync. Em outras palavras, o KMD deve se comportar como se o flip lhe fosse enviado pelo sistema operacional exatamente no TargetFlipTime, com os mesmos sinalizadores e parâmetros.
Por exemplo, se FlipOnNextVSync estiver definido como 1 e TargetFlipTime estiver no meio do quadro, o inverso só deverá ser exibido no próximo VSync.
Suporte ao FlipOverwrite 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 aderir à fila de inversão de hardware definindo MaxHwQueuedFlips para um valor maior que 1.
Várias inversões com um TargetFlipTime expirado
Quando há vários flips na fila com um TargetFlipTime expirado para um determinado plano MPO, a fila de exibição de hardware deve escolher o flip expirado mais recentemente na fila e enviá-lo para exibição. O restante dos flips expirados deve ser tratado como cancelado, e as entradas do log da fila de inversão correspondentes para eles devem conter DXGK_HWFLIPQUEUE_TIMESTAMP_CANCELLED como os valores PresentTimestamp.
Interação entre Duração e TargetFlipTime
O parâmetro Duration na estrutura DXGKARG_SETVIDPNSOURCEADDRESSWITHMULTIPLANEOVERLAY3 deve ser aplicado quando o flip especificado nesta estrutura for exibido 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 Server 2022, a fim de 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.
Mapeamento de 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 flip de destino exatamente no tempo de VSync pretendido no qual o flip deve atingir a tela resulta em falhas frequentes. Essas falhas ocorrem devido à perda de sincronização vertical quando o tempo de VSync real desvia 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 momento de virada de destino.
TargetFlipTime = PreviousFlipStartVSyncTime + (PreviousFlipPresentInterval * FixedRefreshRate) - (FixedRefreshRate / 2)
Intervalos de mapeamento quando o recurso WDDM 2.9 da taxa de atualização virtual estiver presente
O recurso de taxa de atualização virtual pode aumentar temporariamente a taxa de atualização da tela para um múltiplo inteiro da taxa de atualização atual (ou seja, de 24 Hz 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 uma não múltipla
Quando a taxa de atualização é alterada para uma não múltipla de uma taxa de atualização atual (por exemplo, de 24 Hz para 60 Hz), o sistema operacional precisa inspecionar os giros na fila para ver se o tempo de alvo calculado ainda é válido para a nova taxa de atualização. Se o tempo de troca alvo precisar ser alterado, o sistema operacional cancelará as trocas que estão na fila e as recolocará com os tempos de troca alvo que foram recém-calculados.