하드웨어 대칭 이동 큐

이 문서에서는 Windows 11(WDDM 3.0)부터 지원되는 하드웨어 대칭 이동 큐 기능에 대해 설명합니다. 하드웨어 대칭 이동 큐를 사용하면 이후의 여러 프레임을 디스플레이 컨트롤러 큐에 제출할 수 있습니다. 디스플레이 컨트롤러가 여러 개의 대기 중인 프레임을 처리하는 동안 CPU 및 GPU의 일부가 더 낮은 전원 상태로 전환되어 지원되는 하드웨어에서 비디오 재생 시나리오의 전원 효율성을 향상시킬 수 있습니다.

사전 WDDM 3.0 대칭 이동 큐 모델

많은 최신 디스플레이 컨트롤러는 시퀀스에 표시할 여러 프레임을 큐에 대기하는 기능을 지원합니다. WDDM 2.1부터 OS는 다음 VSync에 제공될 여러 미해결 대칭 이동 덮어쓰기 요청을 지원합니다. KMD(디스플레이 미니포트 드라이버)는 DXGK_DRIVERCAPS MaxQueuedMultiPlaneOverlayFlipVSync 값을 통해 이 지원을 나타냅니다. 이 기능은 여러 프레임이 간격 0으로 순차적으로 렌더링되는 높은 프레임 속도의 게임 시나리오에서 대기 시간을 줄이는 데 유용하며, 가장 최근의 프레임만 표시하려고 합니다.

비디오 재생 시나리오에서 순차적으로 표시할 여러 미래 프레임의 콘텐츠는 미리 알려져 있으며 GPU에 큐에 대기할 수 있습니다. 이러한 사전 큐를 사용하면 대기 중인 프레임이 처리되는 동안 CPU가 저전력 상태로 전환되어 상당한 전력 절약이 가능합니다. 그러나 WDDM 3.0 이전에는 OS가 추가 CPU 개입 없이 VSync 간격을 하나 이상 화면에 유지해야 하는 프레임을 둘 이상 제출하는 메커니즘이 없었습니다. 기본 하드웨어 대칭 이동 큐 섹션에는 CPU가 낮은 전원 상태를 입력하고 대기 중인 프레임 처리를 GPU로 오프로드할 수 있는 솔루션이 도입되었습니다.

WDDM 3.0 이전의 게임 시나리오에서는 GPU가 장면을 스왑 체인 백 버퍼에 렌더링한 후 프레임 콘텐츠를 화면에 표시하는 요청을 제출하기 위해 CPU에 대한 왕복이 있습니다. VSync에 가깝게 완료되는 많은 GPU 워크로드의 경우 이 왕복으로 인해 프레임이 지연되고 의도한 대상 시간이 누락되어 관찰 가능한 프레임 결함이 발생할 수 있습니다. 고급 하드웨어 대칭 이동 큐 섹션에는 이 CPU 왕복을 방지하고 완료된 프레임을 짧은 대기 시간으로 화면에 표시하는 메커니즘이 도입되었습니다. 고급 하드웨어 대칭 이동 큐에는 기본 하드웨어 대칭 이동 큐와 GPU 하드웨어 예약 2 단계 기능이 모두 있어야 합니다.

기본 하드웨어 대칭 이동 큐

다음 다이어그램에서는 각각 하나의 VSync 간격 동안 화면에 유지되는 세 개의 프레임을 표시하는 경우를 보여 줍니다.

각각 하나의 VSync 간격으로 화면에 유지되는 세 개의 프레임을 보여 주는 다이어그램.

다이어그램의 채우기 패턴은 Dxgkrnl 소프트웨어 대칭 이동 큐 처리 및 애플리케이션 스레드가 절전 모드를 해제하고 CPU 작업을 수행해야 하는 시간을 보여 줍니다. 각 VSync에서 디스플레이 컨트롤러는 완료된 대칭 이동에 대해 OS에 CPU 알림을 실행해야 하며 OS는 다음 대칭 이동 요청을 제출해야 합니다. 또한 애플리케이션은 각 VSync에서 절전 모드를 해제하고 통계를 쿼리하여 3개의 배치에서 마지막 프레임이 표시되는 시기를 파악해야 합니다.

디스플레이 컨트롤러 큐에 여러 이후 프레임을 제출할 수 있는 하드웨어 대칭 이동 큐 DDI는 WDDM 3.0부터 사용할 수 있습니다. 앞에서 설명한 것처럼 이 메커니즘을 사용하면 디스플레이 컨트롤러가 여러 개의 대기 중인 프레임을 처리하는 동안 CPU 및 GPU의 일부가 더 낮은 전원 상태로 전환될 수 있습니다. 이러한 전환은 지원되는 하드웨어에서 비디오 재생 시나리오의 전력 효율성을 향상시킵니다.

다음 다이어그램에서는 제안된 아키텍처를 보여 줍니다.

기본 하드웨어 대칭 이동 큐 메커니즘을 보여 주는 다이어그램

하드웨어 대칭 이동 큐 접근 방식을 사용하면 애플리케이션과 Dxgkrnl CPU 구성 요소가 모두 v2v4 시간 사이에 두 개의 VSync 간격으로 완전히 유휴 상태이므로 CPU가 낮은 전원 상태로 전환할 수 있습니다. CPU는 애플리케이션이 대기를 요청한 프레임 N+2 가 완료된 경우에만 알림을 받습니다.

고급 하드웨어 대칭 이동 큐

WDDM 3.0 이전의 게임 시나리오에서는 GPU가 장면을 스왑 체인 백 버퍼에 렌더링한 후 프레임 콘텐츠를 화면에 표시하는 요청을 제출하기 위해 CPU에 대한 왕복이 있습니다. 다음 다이어그램은 이 시나리오를 보여줍니다.

CPU 왕복이 필요한 프레임 완성을 보여 주는 다이어그램

다음 다이어그램과 같이 렌더링이 VSync에 너무 가깝게 완료된 경우 이 왕복 비용 때문에 프레임이 대상을 놓칠 수 있습니다.

필요한 CPU 왕복으로 인해 누락된 프레임을 보여 주는 다이어그램

일부 디스플레이 컨트롤러는 기본적으로 GPU가 CPU 왕복 없이 프레임 렌더링을 완료한 후 디스플레이가 대칭 이동 요청을 제출할 수 있도록 하는 대기 조건을 지원합니다. 하드웨어 대칭 이동 큐는 CPU 왕복 없이 완성된 프레임 N 을 디스플레이에 제출할 수 있으므로 다음 다이어그램과 같이 누락된 프레임을 방지할 수 있습니다.

CPU 왕복 없이 프레임 완성을 표시하는 다이어그램

이 문서의 나머지 부분에서는 기본 하드웨어 대칭 이동 큐 기능에 대해 설명합니다.

DDI 지원

하드웨어 대칭 이동 큐 기능을 지원하기 위해 다음 DPI가 추가되었습니다.

기능 가용성 확인

하드웨어 대칭 이동 큐에는 OS 사용/사용 안 함 협상이 필요합니다. 하드웨어 대칭 이동 큐를 지원하는 KMD는 OS에서 하드웨어 대칭 이동 큐를 사용하도록 설정할 수 있는지 여부를 확인하기 위해 DXGK_FEATURE_HWFLIPQUEUE FeatureId사용하여 디바이스 시작 시간 동안 먼저 DXGKCB_QUERYFEATURESUPPORT 호출 해야 합니다.

하드웨어 대칭 이동 큐는 콜백이 성공하고 사용 이 TRUE로 설정된 경우에만 사용할 수 있습니다.

KMD는 하드웨어 대칭 이동 큐 가져오기 및 실험 단계 중에 다음 샘플 코드를 사용할 수 있습니다.


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.
}

드라이버를 가져오는 동안 GPU 하드웨어 예약을 사용하도록 설정하지 않고 하드웨어 대칭 이동 큐를 사용하도록 설정할 수 있지만 이 조합은 공식적으로 지원되지 않습니다. Windows는 현재 공식적으로 릴리스된 드라이버에서 기본 하드웨어 대칭 이동 큐를 사용하도록 설정하기 위해 GPU 하드웨어 예약을 사용하도록 설정해야 합니다.

하드웨어 큐 기능 표시

하드웨어 대칭 이동 큐 지원을 나타내기 위해 MaxHwQueuedFlips가 DXGK_DRIVERCAPS 추가되었습니다. OS에서 앞에서 설명한 대로 하드웨어 대칭 이동 큐 지원을 허용한 경우 하드웨어 대칭 이동 큐를 지원하는 KMD는 MaxHwQueuedFlips를 1보다 큰 값으로 설정해야 합니다. MaxHwQueuedFlips가 1보다 크면 KMD는 디스플레이 하드웨어가 GPU에서 지정된 VidPnSource에 대해 표시될 큐에 대기할 수 있는 MaxHwQueuedFlips 이후 프레임까지 지원한다는 것을 나타냅니다. OS는 미리 큐에 대기할 수 있는 대칭 이동 유형에 대한 드라이버 제공 제한을 적용합니다.

HwQueuedFlipCaps도 DXGK_DRIVERCAPS 추가되었습니다. 이 멤버는 현재 시스템 사용을 위해 예약되어 있습니다. 드라이버는 사용하지 않아야 합니다.

대상 시간 및 대상 타임스탬프 형식 대칭 이동

OS가 하드웨어 대칭 이동 큐에 대칭 이동 요청을 제출하면 대상 대칭 이동 시간도 전송됩니다. 대상 대칭 이동 시간에 도달하면 대칭 이동이 사용자에게 표시될 수 있습니다.

OS는 KeQueryPerformanceCounter에서 가져온 CPU 클록 카운터 단위를 사용하여 대상 프레임 시간을 전달하고 실제 프레임 시간을 해석합니다.

대기 중인 대칭 이동 제출

KMD의 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 콜백 함수에 전달되는 DXGKARG_SETVIDPNSOURCEADDRESSWITHMULTIPLANEOVERLAY3 구조체는 대기 중인 대칭 이동 제출을 사용하도록 다음과 같이 수정되었습니다.

  • OutputFlagsDXGK_SETVIDPNSOURCEADDRESS_OUTPUT_FLAGS 구조에 다음 세 멤버가 추가되었습니다. 이러한 멤버에 대한 자세한 내용은 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 재시도 및 실패 사례를 참조하세요.

    • HwFlipQueueDrainNeeded
    • HwFlipQueueDrainAllPlanes
    • HwFlipQueueDrainAllSources
  • TargetFlipTime 멤버가 추가되었습니다. TargetFlipTime 은 QPC 단위의 대상 대칭 이동 시간을 설명합니다. 클록이 이 값에 도달하면 VSync를 적용하고 플래그를 떼어내는 동안 프레임을 디스플레이로 보낼 수 있습니다. 이전에 대기 중인 보류 중인 대칭 이동이 있는 경우 OS는 대칭 이동 요청 에서 참조하는 각 MPO 평면에 대해 TargetFlipTime 이 이 평면에 대해 보류 중인 대칭 이동 대상 시간보다 크거나 같은지 확인합니다. 즉, 타임스탬프가 동일하거나 증가하는 대칭 이동 시퀀스가 있을 수 있지만 시간을 거슬러 올라가는 시퀀스는 있을 수 없습니다.

DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 재시도 및 실패 사례

보류 중인 대칭 이동으로 인해 하드웨어에 대한 요청을 큐에 대기하지 못했습니다.

다른 대칭 이동 요청이 보류 중인 동안 KMD가 대칭 이동 요청을 큐에 대기하지 못하게 할 수 있는 몇 가지 특별한 경우가 있습니다. 이러한 경우 KMD는 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3에서 STATUS_RETRY 반환하고 HwFlipQueueDrainNeed를 1로 설정해야 합니다. OS는 대칭 이동의 영향을 받는 평면에서 보류 중인 모든 대칭 이동이 완료된 후 대상 시간에 도달하면 다시 플립 요청을 제출하려고 시도합니다.

경우에 따라 디스플레이 하드웨어는 들어오는 대칭 이동 요청에서 참조하는 것뿐만 아니라 모든 평면에서 보류 중인 대칭 이동이 완료되어야 할 수 있습니다. 이 경우 HwFlipQueueDrainNeeded 및 HwFlipQueueDrainAllPlanes 플래그는 모두 1로 설정해야 하며 KMD는 STATUS_RETRY 반환해야 합니다.

마찬가지로 디스플레이 하드웨어는 내부 리소스를 다시 할당하기 위해 모든 VidPn 원본에서 보류 중인 대칭 이동이 완료되어야 할 수 있습니다. 이 경우 HwFlipQueueDrainAllSourcesHwFlipQueueDrainNeeded 플래그를 설정해야 하며 KMD는 STATUS_RETRY 반환해야 합니다.

또한 KMD는 디바이스 IRQL(PrePresentNeeded 가 0으로 설정됨)에서 다시 제출을 수행해야 하는지 또는 OS가 PASSIVE_LEVEL(PrePresentNeeded 를 1로 설정)에서 이 호출을 수행해야 하는지 여부를 OS에 나타낼 수 있습니다. 해당 VidPnSourceId에 보류 중인 대칭 이동이 더 이상 없더라도 KMD가 여전히 STATUS_RETRY 반환하는 경우 이 조건은 잘못된 매개 변수 오류처리됩니다.

MaxHwQueuedFlips은 MPO 평면에 큐에 대기할 수 있는 간단한 주소 전용 변경 대칭 이동의 최대 수를 여전히 반영하는 것이 중요합니다. STATUS_RETRY 메커니즘은 평면 구성 변경과 같이 대기 대기할 수 없는 더 복잡한 대칭 이동 요청에 사용해야 합니다.

잘못된 매개 변수 오류

하드웨어 대칭 이동 큐 모델에서 OS의 실패한 대칭 이동 요청 처리는 디버깅 기능을 향상하기 위해 재작업되었습니다. KMD가 대칭 이동 요청을 처리할 수 없는 경우 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3에서 STATUS_INVALID_PARAMETER 반환해야 합니다. OS 설정에 따라 OS는 다음 작업 중 하나를 수행합니다.

  • 커널 디버거 중단 및 버그 검사: 이 동작은 종종 개발/시험판 빌드에서 사용하도록 설정되어 오류 조건이 발생할 때 디버깅 기능을 향상합니다.
  • 라이브 커널 덤프 다음에 TDR: 소매 최종 사용자 동작이 뒤따릅니다.

VSync 인터럽트 동작 지정

대기 중인 대칭 이동 시나리오에서 전원을 절약하기 위해 OS는 CPU를 저전력 상태로 유지하기 위해 정기적인 VSync 인터럽트를 일시 중단하는 경우가 많습니다. 그러나 일부 대칭 이동은 애플리케이션이 완료된 선물의 일괄 처리를 관찰하고 추가 작업을 큐에 대기하기 위해 인터럽트를 발생시키는 것으로 표시됩니다. 보류 중인 대칭 이동 요청이 있는지 여부에 관계없이 애플리케이션이 모든 VSync 인터럽트에서 절전 모드 해제를 요청하는 경우도 있습니다. 반대로 완전히 유휴 상태인 시스템에서는 새 프레젠테이션 활동 또는 VSync 수신기가 나타날 때까지 VSync 인터럽트를 일시 중단합니다.

이러한 모든 경우를 처리하기 위해 다음 드라이버 콜백 및 콜백 구조가 도입되었습니다.

KMD는 DRIVER_INITIALIZATION_DATA DxgkDdiSetInterruptTargetPresentId 함수에 대한 포인터를 제공합니다.

OS는 DxgkDdiSetInterruptTargetPresentId를 호출하여 해당 대칭 이동이 완료될 때 VSync 인터럽트가 발생하는 대상 PresentId를 지정합니다. 이 함수는 DxgkDdiSetVidPnSourceAddressVSync 인터럽트와 동기화하기 위해 DIRQL(디바이스 인터럽트 수준)에서 호출됩니다.

DxgkDdiControlInterrupt와의 상호 작용

DxgkDdiControlInterrupt DxgkDdiControlInterrupt2/DxgkDdiControlInterrupt3/을 통해 VSync 인터럽트를 완전히 사용하지 않도록 설정하면 인터럽트 대상 PresentId 값에 관계없이 사용하지 않도록 유지됩니다. KMD는 VSync를 다시 사용하도록 설정한 후에 적용할 수 있도록 최신 인터럽트 대상 현재 ID를 저장해야 합니다.

DxgkDdiControlInterrupt Xxx를 통해 VSync 인터럽트를사용하는 경우 인터럽트 대상 현재 ID(pSetInterruptTargetPresentId)는 다음과 같이 세분화된 제어를 제공합니다.

  • 대상 현재 ID가 UINT64_MAX 설정되면 대상 현재 ID가 다시 변경될 때까지 앞으로 VSync 인터럽트는 필요하지 않습니다. VSync 인터럽트는 사용하지 않도록 설정되지만 KMD는 인터럽트 다시 활성화를 위해 DXGK_VSYNC_DISABLE_KEEP_PHASE 동작을 구현해야 합니다.

  • 대상 현재 ID를 0으로 설정하면 모든 VSync에 인터럽트 필요.

  • 다른 현재 ID 값의 경우 현재 스캔한 PresentId = InterruptTargetPresentId>인 경우 인터럽트가 발생합니다.

여러 MPO 평면을 사용할 수 있는 경우 필요한 평면이 있으면 VSync 인터럽트(인터럽트)를 발생시켜야 합니다.

DxgkDdiSetInterruptTargetPresentId를 사용하여 2단계 VSync 사용 안 함

OS가 DxgkDdiSetInterruptTargetPresentId를 호출하는 경우 이 VidPnSource에서 VSync를 완전히 사용하지 않도록 설정하는 평면에서 InterruptTargetPresentId를 설정합니다. 이 평면은 VSync를 사용하도록 설정한 마지막 평면이었으며, 이제 이 평면도 VSync를 사용하지 않도록 설정됩니다. KMD는 VSync 인터럽트 기능을 사용하지 않도록 설정해야 하지만 하드웨어에서 VSync 단계를 사용하도록 설정(DXGK_VSYNC_DISABLE_KEEP_PHASE)해야 합니다. 특정 기간(일반적으로 두 VSync 기간과 동일) 후에 OS는 DXGK_VSYNC_DISABLE_NO_PHASE DxgkDdiControlInterrupt Xxx에 대한 호출과 함께 후속작업을 수행합니다. 이 호출을 통해 KMD는 VSync 단계 및 VSync 클록을 사용하지 않도록 설정하여 최대 전력을 절약하고 비하르트웨어 플립 큐 시스템과 성능 패리티를 유지할 수 있습니다.

대기 중 대칭 이동 취소

전체 화면 상태 전환 또는 애플리케이션 종료와 같은 경우 향후 대기 중인 대칭 이동은 취소해야 할 수 있습니다. 이러한 경우를 처리하기 위해 다음 드라이버 콜백 및 관련 구조가 도입되었습니다.

KMD는 DRIVER_INITIALIZATION_DATA DxgkDdiCancelFlips 함수에 대한 포인터를 제공합니다.

OS는 DxgkDdiCancelFlips를 호출할 때 취소할 대기 중인 대칭 이동 범위를 지정하고 KMD는 동기적으로 취소할 수 있었던 대칭 이동 범위를 OS에 다시 보고합니다.

다음 예제에서는 단일 평면에서 대칭 이동 취소의 메커니즘 및 동기 사례를 보여 줍니다. (OS는 Windows 11 버전 22H2에서 비동기 취소를 지원하지 않습니다.) 다음 대칭 이동이 하드웨어 대칭 이동 큐에 큐에 대기되고 있다고 상상해 보세요.

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

그런 다음 OS는 N+2, N+3N+4 대칭 이동 취소를 결정하므로 PresentIdCancelRequested가 N+2설정된 DxgkDdiCancelFlips호출합니다.

KMD는 하드웨어 대칭 이동 큐 상태를 검사할 때 다음을 결정합니다.

  • 대칭 이동 N+2 는 이미 디스플레이 하드웨어로 전송되었으며 호출 시 취소할 수 없습니다.
  • 대칭 이동 N+3N+4는 부작용 없이 하드웨어 대칭 이동 큐에서 동기적으로 제거할 수 있습니다.

따라서 KMD는 PresentIdCancelled를 N+3으로 설정하고 평소와 같이 N+2를 완료합니다.

OS는 N+3 및 N+4를 취소된 것으로 표시하고 N, N+1, N+2를 비행 중인 것으로 처리합니다. 다음 VSync 인터럽트 발생 시 대칭 이동 큐 로그는 평소와 같이 N, N+1, N+2에 대한 타임스탬프를 나타냅니다.

동기적으로 취소된 대칭 이동 범위는 연속되어야 하며, 0이 아닌 경우 KMD에 제출된 마지막 현재 ID를 포함하는 것으로 간주됩니다. 즉, 두 동기 취소된 대칭 이동 범위 내에 간격이 없을 수 있습니다.

여러 평면에서 인터로킹된 대칭 이동 취소

여러 평면 및 PresentIds를 사용하여 DxgkDdiSetVidPnSourceAddress를 호출하여 인터록된 대칭 이동이 제출됩니다. OS와 KMD 간의 계약은 다음과 같습니다.

  • 평면 집합은 동일한 VSync에 표시되어야 합니다.
  • 디스플레이 하드웨어는 하나의 VSync에 이러한 평면의 하위 집합만 표시하고 나머지는 다음 VSync에 표시할 수 없습니다.

하드웨어 대칭 이동 큐 모델에서는 DxgkDdiCancelFlips에 대한 호출에서 여러 평면 및 PresentId를 전달하여 이러한 상호 잠긴 대칭 이동이 취소됩니다. 이러한 경우에 전달된 평면 집합은 보류 중인 인터로킹된 플립 요청에 해당해야 하며, 연결된 모든 PresentId에 대한 KMD의 결정은 동일해야 합니다.

  • 취소 안 함 또는
  • 동기적으로 취소

DxgkDdiCancelFlips는 DxgkDdiSetVidPnSourceAddress 및 VSync 인터럽트와 동기화하기 위해 DIRQL(디바이스 인터럽트 수준)에서 호출됩니다.

대기 중인 대칭 이동에 대한 현재 통계 가져오기

하드웨어 대칭 이동 큐 접근 방식은 각 VSync에서 CPU를 깨우지 않도록 하기 위한 것이므로 마지막 몇 번의 대기 중인 대칭 이동에 대한 프레임 표시 시간을 유지하는 메커니즘이 있어야 합니다.

하드웨어 대칭 이동 큐를 지원하는 그래픽 드라이버는 각 활성 VidPnSource에 대해 지정된 MPO 평면에 대해 완료되거나 취소된 각 대칭 이동에 대한 OS 제공 플립 큐 로그 버퍼에 정보를 기록해야 합니다.

OS는 각 활성 VidPnSource에 대해 지정된 MPO 평면에 대한 첫 번째 DxgkDdiSetVidPnSourceAddress 호출 전에 대칭 이동 큐 로그 포인터(DxgkDdiSetFlipQueueLogBuffer 호출)를 제공합니다. 대칭 이동 큐에 미해결 요청이 없는 경우 OS에서 대칭 이동 큐 로그 버퍼를 삭제할 수 있습니다. 이 경우 다음 DxgkDdiSetVidPnSourceAddress 호출 전에 새 로그 포인터를 제공합니다. 대칭 이동 큐 로그는 순환입니다. [NumberOfEntries-1] 항목이 작성되면 다음 로그 항목은 [0]입니다.

대기 중인 대칭 이동의 일괄 처리가 완료되면 KMD는 완료된 대칭 이동에 대한 대칭 이동 큐 로그가 다음 두 지점의 가장 빠른 시간에 업데이트되도록 보장해야 합니다.

  • 인터럽트를 발생시키는 데 필요한 대칭 이동에 대한 VSync 인터럽트 처리기입니다.
  • OS의 명시적 DxgkDdiUpdateFlipQueueLog 요청에 대한 응답입니다.

대칭 이동 큐 로그 DDI

다음 대칭 이동 큐 로그 관련 콜백 및 관련 구조가 추가되었습니다.

KMD는 DRIVER_INITIALIZATION_DATA 함수에 대한 포인터를 제공합니다.

VSync 인터럽트 구조 업데이트

하드웨어 대칭 이동 큐 모델에 대한 VSync 인터럽트 구현을 위해 DXGKARGCB_NOTIFY_INTERRUPT_DATA 구조가 다음과 같이 변경되었습니다.

  • DXGK_INTERRUPT_CRTC_VSYNC_WITH_MULTIPLANE_OVERLAY3 열거형 값이 InterruptType으로 추가되었습니다.
  • CrtcVSyncWithMultiPlaneOverlay3 구조체가 공용 구조체에 추가되었습니다. CrtcVSyncWithMultiPlaneOverlay3의 의미 체계는 기존 CrtcVSyncWithMultiPlaneOverlay2 구조체와 유사합니다. 각 평면 에 대해 마지막으로 완료된 단일 PresentId 대신 CrtcVSyncWithMultiPlaneOverlay3.pMultiPlaneOverlayVSyncInfo 는 대칭 이동 큐 로그에서 이전에 보고되지 않은 PresentId의 범위를 가리킵니다.
  • crtcVSyncWithMultiPlaneOverlay3의 pMultiPlaneOverlayVSyncInfo 멤버에 대해 DXGK_MULTIPLANE_OVERLAY_VSYNC_INFO3 구조가 추가되었습니다.

기본 하드웨어 대칭 이동 큐 예제 다이어그램을 다시 사용합니다.

기본 하드웨어 대칭 이동 큐 메커니즘을 보여 주는 다이어그램

Flip N이 제출될 때 FirstFreeFlipQueueLogEntryIndex가 40으로 설정된 다음 N, N+1, N+2 선물이 완료되었다고 가정 합니다.

단일 평면 구성이 각각 v2, v3, v4에서 3개의 PresentIds N, N+1N+2 를 완료한 후 KMD는 인덱스 40, 41 및 42를 사용하여 대칭 이동 큐 로그 버퍼에 세 개의 새 항목을 작성했습니다. KMD는 CrtcVSyncWithMultiPlaneOverlay3 구조체에서 FirstFreeFlipQueueLogEntryIndex 값이 43이라고 보고합니다. OS는 FirstFreeFlipQueueLogEntryIndex40에서 43으로 변경되고 로그 항목 40, 41 및 42에서 읽는 것을 관찰합니다. KMD는 다음과 같이 다음 대칭 이동 큐 로그 버퍼 값을 설정해야 합니다.

  • VidPnTargetId: CrtcVSyncWithMultiPlaneOverlay2와 동일한 의미

  • PhysicalAdapterMask: 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

명시적 대칭 이동 큐 로그 업데이트 요청

OS가 VSync 인터럽트 대기 없이 마지막으로 완료된 대칭 이동 일괄 처리에 대한 정보를 가져와야 하는 경우가 있습니다. 이러한 경우 OS는 DxgkDdiUpdateFlipQueueLog를 명시적으로 호출하여 KMD가 독점 디스플레이 하드웨어 데이터 구조에서 읽도록 요청하고 과거 플립 정보를 대칭 이동 큐 로그에 씁니다. 로그의 의미 체계는 앞에서 설명한 것과 동일합니다. 유일한 변경 내용은 FirstFreeFlipQueueLogEntryIndex 가 VSync 인터럽트 외부의 OS로 반환된다는 것입니다.

DxgkDdiUpdateFlipQueueLog는 DIRQL(디바이스 인터럽트 수준)에서 호출되며 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 DDI와 동일한 동기화 클래스에 있습니다.

하드웨어 대칭 이동 큐에서 대기 중인 대칭 이동이 있는 상태에서 디스플레이 모드 변경 및 전원 전환

Dxgkrnl 은 모드 변경을 시작하거나 모니터 전원을 켜기 전에 하드웨어 대칭 이동 큐에서 이미 대기 중인 대칭 이동이 완료되거나 취소되도록 합니다.

하드웨어 대칭 이동 큐 타임스탬프에 프레젠테이션 요청 매핑

특정 어댑터에서 하드웨어 대칭 이동 큐를 사용하도록 설정하면 타임스탬프에 모든 대칭 이동 호출이 수반됩니다. 즉, KMD는 이전 및 새 DxgkDdiSetVidPnSourceAddress 의미 체계의 혼합을 처리할 필요가 없습니다.

OS는 기존 간격 기반 Present API 요청을 KMD에 대한 타임스탬프 기반 대칭 이동 호출로 자동으로 변환합니다. 다음 섹션에서는 다양한 사례와 이러한 사례가 KMD에서 받은 플래그, 기간 및 타임스탬프의 조합에 매핑되는 방법에 대해 설명합니다.

떼어내기 및 비정상 대칭 이동 의미 체계

하드웨어 대칭 이동 큐를 사용하는 경우 대칭 이동 해제의 의미 체계는 개념적으로 동일합니다. TargetFlipTime 도달하면 KMD는 FlipImmediate, FlipImmediateNoTearing 및 FlipOnNextVSync같은 플래그를 계속 적용하면서 표시할 대칭 이동을 제출해야 합니다. 즉, KMD는 OS가 동일한 대칭 이동 플래그 및 매개 변수를 사용하여 TargetFlipTime에서 정확히 대칭 이동을 제출한 것처럼 동작해야 합니다.

예를 들어 FlipOnNextVSync가 1로 설정되어 있고 TargetFlipTime이 프레임 중간에 있는 경우 대칭 이동은 다음 VSync에만 표시되어야 합니다.

FlipOverwrite 지원 및 하드웨어 대칭 이동 큐

하드웨어 대칭 이동 큐는 DXGK_DRIVERCAPS MaxQueuedMultiPlaneOverlayFlipVSync으로 제어되는 대칭 이동 덮어쓰기 기능의 엄격한 상위 집합입니다.

따라서 드라이버가 MaxHwQueuedFlips 를 1보다 큰 값으로 설정하여 하드웨어 대칭 이동 큐에 옵트인하는 경우 OS는 MaxQueuedMultiPlaneOverlayFlipVSync 값을 무시합니다.

만료된 TargetFlipTime을 사용하여 여러 대칭 이동

지정된 MPO 평면에 대해 만료된 TargetFlipTime 을 사용하여 여러 개의 대기 중인 대칭 이동이 있는 경우 하드웨어 디스플레이 큐는 가장 최근에 대기 중인 만료된 대칭 이동 항목을 선택하고 이를 제출하여 표시해야 합니다. 만료된 나머지 대칭 이동은 취소된 것으로 처리되어야 하며 해당 대칭 이동 큐 로그 항목에는 PresentTimestamp 값으로 DXGK_HWFLIPQUEUE_TIMESTAMP_CANCELLED 포함되어야 합니다.

Duration과 TargetFlipTime 간의 상호 작용

이 구조체에 지정된 대칭 이동이 화면에 표시되면 DXGKARG_SETVIDPNSOURCEADDRESSWITHMULTIPLANEOVERLAY3 구조체의 Duration 매개 변수가 적용됩니다. 모든 평면에서 VidPnSourceId에 지정된 출력에 대해 원하는 새로운 디스플레이 새로 고침 속도 동작을 지정합니다. WDDM 3.1 및 Windows Server 2022 릴리스에서 대기 중인 사용자 지정 기간 변경을 지원하지 않는 하드웨어에 대한 드라이버 구현을 간소화하기 위해 OS는 이전 대칭 이동 요청이 완료된 후 새 Duration 매개 변수를 사용하여 대칭 이동 요청만 제출합니다.

TargetFlipTime에 프레젠테이션 간격 매핑

새로 고침 빈도가 고정된 경우의 매핑 간격

기존 현재 간격 의미 체계를 유지하려면 OS는 현재 간격 및 새로 고침 속도를 사용하여 대상 대칭 이동 시간을 계산해야 합니다. 그러나 대상 대칭 이동 시간을 대칭 이동이 화면에 적중해야 하는 의도된 VSync 시간으로 정확하게 설정하면 결함이 자주 발생합니다. 이러한 결함은 실제 VSync 타이밍이 약간 드리프트되는 경우 누락된 VSync 때문입니다. OS는 결함으로부터 보호하기 위해 계산된 대상 대칭 이동 시간에서 VSync 간격의 절반을 뺍니다.

다음은 현재 간격을 대상 대칭 이동 시간에 매핑하기 위한 간단한 수식입니다.

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

가상 새로 고침 속도 WDDM 2.9 기능이 있는 경우의 매핑 간격

가상 새로 고침 속도 기능은 디스플레이 새로 고침 속도를 현재 새로 고침 속도의 정수 배수로 일시적으로 높일 수 있습니다(즉, 24Hz를 144Hz 또는 192Hz로 높일 수 있습니다). 이 향상을 지원할 수 있는 디바이스의 경우 이전 섹션의 수식은 현재 새로 고침 속도 중 가장 빠른 배수를 사용하도록 수정됩니다.

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

새로 고침 빈도가 비멀티플로 변경될 때의 매핑 간격

새로 고침 빈도가 현재 새로 고침 속도의 24Hz에서 60Hz로 변경되면 OS는 계산된 대상 시간이 새 새로 고침 속도에 여전히 유효한지 확인하기 위해 큐 대칭 이동을 검사해야 합니다. 대상 대칭 이동 시간을 변경해야 하는 경우 OS는 대기 중인 대칭 이동을 취소하고 새로 계산된 대상 대칭 이동 시간으로 다시 큐에 넣습니다.