硬體翻轉佇列
本文說明從 Windows 11 開始支援的硬體翻轉佇列功能(WDDM 3.0)。 硬體翻轉佇列可讓多個未來的畫面提交到顯示控制器佇列。 當顯示控制器正在處理多個佇列畫面時,GPU 的 CPU 和部分可以轉換為較低的電源狀態,以改善支援硬體上視訊播放案例的電源效率。
WDDM 3.0 翻轉佇列模型
許多新式顯示器控制器都支援將序列中顯示的多個畫面排入佇列的能力。 從WDDM 2.1 開始,OS 支援多個未處理的翻轉覆寫要求,這些要求將在下一個 VSync 上呈現。 顯示迷你埠驅動程式 (KMD) 會透過 DXGK_DRIVERCAPS 中的 MaxQueuedMultiPlaneOverlayFlipVSync 值來表示這項支援。 這項功能適用於降低高幀速率遊戲案例的延遲,其中多個畫面會以間隔 0 循序轉譯,並意圖只顯示最新的畫面格。
在影片播放案例中,會事先知道要循序顯示之多個未來畫面的內容,並可排入 GPU 佇列。 此進階佇列可讓 CPU 在處理佇列框架時進入低電源狀態,進而節省大量電源。 不過,在WDDM 3.0之前,沒有機制可讓OS提交多個畫面需要停留在畫面上至少一個 VSync 間隔,而不需進一步的 CPU 介入。 [基本硬體翻轉佇列] 區段引進了一個解決方案,可讓 CPU 進入低電源狀態,並將佇列框架處理卸除至 GPU。
在WDDM 3.0 之前的遊戲案例中,GPU 完成將場景轉譯至交換鏈結返回緩衝區之後,CPU 會往返 CPU,以提交要求以將畫面內容呈現至畫面。 對於接近 VSync 的繁重 GPU 工作負載,此往返可能會導致畫面延遲並遺漏預定的目標時間,而導致可觀察到的畫面故障。 [進階硬體翻轉佇列] 區段引進了一種機制,以避免此 CPU 往返,並將已完成的畫面畫面呈現低延遲。 進階硬體翻轉佇列需要有基本的硬體翻轉佇列和 GPU 硬體排程階段 2 功能。
基本硬體翻轉佇列
下圖說明呈現三個畫面的情況,每個畫面都會停留一個 VSync 間隔。
圖表中的填滿模式會顯示 Dxgkrnl 軟體翻轉佇列處理和應用程式線程必須喚醒並執行 CPU 工作的時間。 在每個 VSync 上,顯示控制器必須發出 CPU 通知給操作系統,才能完成翻轉,而且 OS 必須提交下一個翻轉要求。 應用程式也必須在每一個 VSync 上喚醒,並查詢呈現統計數據,以在顯示三個批次的最後一個畫面格時最終得知。
從WDDM 3.0 開始,即可使用可提交多個未來畫面格到顯示控制器佇列的硬體翻轉佇列 DIS。 如先前所述,此機制可讓 GPU 的 CPU 和部分在顯示控制器處理多個佇列畫面時,轉換為較低的電源狀態。 此轉換可改善支持硬體上視訊播放案例的電源效率。
下圖說明建議的架構。
使用硬體翻轉佇列方法,應用程式和 Dxgkrnl CPU 元件在 v2 和 v4 之間的兩個 VSync 間隔完全閒置,讓 CPU 進入低電源狀態。 只有在畫面 N+2 要求等候的應用程式完成時,才會收到 CPU 通知。
進階硬體翻轉佇列
在WDDM 3.0 之前的遊戲案例中,GPU 完成將場景轉譯至交換鏈結返回緩衝區之後,CPU 會往返 CPU,以提交要求以將畫面內容呈現至畫面。 下圖顯示此案例。
如果轉譯太接近 VSync,此往返成本可能會導致畫面格遺漏其目標,如下圖所示。
某些顯示控制器原生支援等候條件,允許顯示在 GPU 完成轉譯畫面時提交翻轉要求,而不需要 CPU 往返。 由於硬體翻轉佇列可以將已完成的畫面 N 提交到顯示器,而不需進行 CPU 往返,因此可能會避免遺漏畫面,如下圖所示。
本文的其餘部分將討論基本硬體翻轉佇列功能。
DDI 支援
已新增下列 DIS 以支援硬體翻轉佇列功能。
檢查功能可用性
硬體翻轉佇列需要 OS 啟用/停用交涉。 支援硬體翻轉佇列的 KMD 必須先在裝置啟動期間呼叫DXGKCB_QUERYFEATURESUPPORT,且具有featureId DXGK_FEATURE_HWFLIPQUEUE,以判斷作業系統是否允許啟用硬體翻轉佇列。
只有在回呼成功且 Enable 設定為 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 表示顯示硬體最多可支援 MaxHwQueuedFlips 未來可排入佇列以供 GPU 上指定 VidPnSource 顯示的畫面。 OS 會接受驅動程式提供的限制,限制可以事先排入佇列的翻轉類型。
HwQueuedFlipCaps 也已新增至 DXGK_DRIVERCAPS。 此成員目前保留供系統使用;驅動程式不應該使用它。
翻轉目標時間和目標時間戳格式
當OS將翻轉要求提交至硬體翻轉佇列時,也會傳送目標翻轉時間。 在達到目標翻轉時間之後,使用者可以看到翻轉。
OS 會使用從 KeQueryPerformanceCounter 取得的 CPU 時鐘計數器單位,傳遞目標框架時間並解譯實際的框架時間。
提交已排入佇列的翻轉
傳遞至 KMD 的 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 回呼函式的 DXGKARG_SETVIDPNSOURCEADDRESSWITHMULTIPLANEOVERLAY3 結構已修改為下列專案,以啟用佇列翻轉的提交:
下列三個成員已新增至 OutputFlags 的 DXGK_SETVIDPNSOURCEADDRESS_OUTPUT_FLAGS 結構。 如需這些成員的詳細資訊,請參閱 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 重試和失敗案例 。
- HwFlipQueueDrainNeeded
- HwFlipQueueDrainAllPlanes
- HwFlipQueueDrainAllSources
已新增 TargetFlipTime 成員。 TargetFlipTime 描述 QPC 單位中的目標翻轉時間。 當時鐘達到這個值時,框架可以傳送至顯示器,同時接受 VSync 和撕裂旗標。 在先前排入佇列的擱置翻轉存在的情況下,OS 會保證針對翻轉要求所參考的每個 MPO 平面, TargetFlipTime 大於或等於此平面的任何擱置翻轉目標時間。 換句話說,可能會有一連串具有相同或增加時間戳的翻轉,但不可能有一個序列會回到時間。
DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 重試和失敗案例
由於擱置翻轉而無法將要求排入硬體佇列
有幾個特殊案例可能會防止 KMD 在其他翻轉要求擱置時將翻轉要求排入佇列。 在這種情況下,KMD 應該從 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 傳回STATUS_RETRY,並將 HwFlipQueueDrainNeeded 設定為 1。 操作系統會在所有受翻轉影響的平面上擱置翻轉完成且達到目標時間之後,再次嘗試提交翻轉要求。
在某些情況下,顯示硬體可能需要在所有平面上完成擱置翻轉,而不只是傳入翻轉要求所參考的翻轉。 在此情況下, HwFlipQueueDrainNeeded 和 HwFlipQueueDrainAllPlanes 旗標都應該設定為 1,KMD 應傳回STATUS_RETRY。
同樣地,顯示硬體可能需要在所有 VidPn 來源上完成擱置翻轉才能重新配置內部資源,在此情況下 ,必須設定 HwFlipQueueDrainAllSources 和 HwFlipQueueDrainNeeded 旗 標,KMD 應該傳回STATUS_RETRY。
此外,KMD 可以向 OS 指出重新提交應該在裝置 IRQL 上完成(PrePresentNeeded 設定為 0),或 OS 是否應在 PASSIVE_LEVEL執行此呼叫(PrePresentNeeded 設定為 1)。 如果 KMD 仍然傳回STATUS_RETRY,即使該 VidPnSourceId 上沒有其他擱置的翻轉,此條件會 被視為無效的參數失敗。
請務必將 MaxHwQueuedFlips 的值仍然反映可排入 MPO 平面的簡單僅限地址變更翻轉數目上限。 STATUS_RETRY機制應該用於無法深度排入佇列的更複雜的翻轉要求,例如平面設定變更。
參數失敗無效
在硬體翻轉佇列模型中,操作系統處理失敗的翻轉要求已重新處理,以提供更好的偵錯能力。 當 KMD 無法處理翻轉要求時,它應該會從 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay3 傳回STATUS_INVALID_PARAMETER。 根據OS設定,OS 會執行下列其中一個動作:
- 內核調試程式中斷和錯誤檢查:在發生失敗狀況時,通常會在開發/發行前版本組建上啟用此行為,以提升偵錯能力。
- 即時核心傾印後面接著 TDR:零售終端用戶行為。
指定 VSync 中斷行為
為了在佇列翻轉案例中實現省電,OS 通常會暫停一般 VSync 中斷,讓 CPU 保持低功率狀態。 不過,有些翻轉標示為需要引發中斷,以便應用程式觀察已完成的簡報批次,並排入進一步的工作佇列。 不論是否有擱置的翻轉要求,應用程式要求在每個 VSync 中斷上喚醒時,也會有這種情況。 相反地,在完全閑置的系統上,VSync 中斷會暫停,直到新的簡報活動或 VSync 接聽程式出現為止。
為了處理所有這些案例,引進了下列驅動程式回呼和回呼結構:
KMD 會在 DRIVER_INITIALIZATION_DATA中提供其 DxgkDdiSetInterruptTargetPresentId 函式的 指標
OS 會呼叫 DxgkDdiSetInterruptTargetPresentId 來指定目標 PresentId ,以在對應的翻轉完成時引發 VSync 中斷。 此函式會在裝置中斷層級呼叫 ,以與 DxgkDdiSetVidPnSourceAddress 和 VSync 中斷同步。
與 DxgkDdiControlInterrupt 互動
當 VSync 中斷完全透過 DxgkDdiControlInterrupt DxgkDdiControlInterrupt2//DxgkDdiControlInterrupt3 停用時,不論中斷目標 PresentId 值為何,它們都會保持停用。 KMD 必須儲存最新的中斷目標目前標識碼,以便在再次啟用 VSync 之後接受它。
透過 DxgkDdiControlInterrupt Xxx 啟用 VSync 中斷時,中斷目標目前標識符 (pSetInterruptTargetPresentId) 會提供更精細的控制,如下所示:
當目標目前標識碼設定為UINT64_MAX時,在目標存在標識符再次變更之前,不需要任何 VSync 中斷。 VSync 中斷已停用,但需要 KMD 才能實 作重新啟用中斷DXGK_VSYNC_DISABLE_KEEP_PHASE 行為。
當目標目前標識碼設定為0時,每個 VSync 都需要中斷。
若為任何其他目前的標識碼值,如果目前掃描的 PresentId >= InterruptTargetPresentId,則會引發中斷。
當有多個 MPO 平面可用時,如果有任何平面需要,就應該引發 VSync 中斷。
使用 DxgkDdiSetInterruptTargetPresentId 停用 2 階段 VSync
如果 OS 呼叫 DxgkDdiSetInterruptTargetPresentId 會在飛機上設定一個 InterruptTargetPresentId,這會導致在此 VidPnSource 上完全停用 VSync(也就是,此平面是保留 VSync 啟用的最後一個平面,而現在此平面也會停用 VSync),KMD 應該停用 VSync 中斷,但在硬體啟用中保留 VSync 階段(DXGK_VSYNC_DISABLE_KEEP_PHASE)。 在一段特定時段之後(通常相當於兩個 VSync 期間),OS 會跟著呼叫 DxgkDdiControlInterruptXxx 與 DXGK_VSYNC_DISABLE_NO_PHASE。 此呼叫可確保 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+3 和 N+4,因此它會呼叫 DxgkDdiCancelFlips ,並將 PresentIdCancelRequested 設定為 N+2。
當 KMD 檢查硬體翻轉佇列狀態時,它會判斷:
- 翻轉 N+2 已傳送至顯示硬體,且無法在通話時取消。
- 翻 轉 N+3 和 N+4 可以從硬體翻轉佇列同步移除,而不會有副作用。
因此,KMD 會將 PresentIdCancelled 設定為 N+3,並照常完成 N+2。
OS 會將 N+3 和 N+4 標示為已取消,並將 N、N+1、N+2 視為在正式發行前小眾測試版中。 引發下一個 VSync 中斷時,翻轉佇列記錄會如往常指出 N、N+1、N+2 的時間戳。
同步取消翻轉的範圍必須是連續的,如果不是零,則會假設包含提交至 KMD 的最後一個目前標識碼。 換句話說,這兩個同步取消的翻轉範圍內都沒有任何間距。
取消多個平面上的聯鎖翻轉
呼叫具有多個平面和 PresentIds 的 DxgkDdiSetVidPnSourceAddress 來提交聯結翻轉。 OS 與 KMD 之間的合約如下:
- 必須在相同的 VSync 上顯示一組平面。
- 不允許顯示硬體只會在一個 VSync 上顯示這些平面的子集,而其餘則顯示在下一個 VSync 上。
在硬體翻轉佇列模型中,透過在呼叫 DxgkDdiCancelFlips 時傳遞多個平面和 PresentIds,取消這類聯結翻轉。 在這類情況下傳遞的平面集合必須對應至擱置的聯鎖翻轉要求,而 KMD 關於所有聯結 PresentId 的決定必須相同:
- 不要取消,或
- 同步取消
DxgkDdiCancelFlips 在裝置中斷層級呼叫 ,以與 DxgkDdiSetVidPnSourceAddress 和 VSync 中斷同步。
取得佇列翻轉的目前統計數據
由於硬體翻轉佇列方法是避免喚醒每個 VSync 上的 CPU,因此必須有一個機制來保留最後數個佇列翻轉的畫面顯示時間。
支援硬體翻轉佇列的圖形驅動程式必須針對每個作用中 VidPnSource 的指定 MPO 平面,將資訊寫入操作系統提供的翻轉佇列記錄緩衝區或取消的翻轉。
OS 保證會在第一個 DxgkDdiSetVidPnSourceAddress 呼叫每個作用中 VidPnSource 的指定 MPO 平面之前,提供翻轉佇列記錄指標(在呼叫 DxgkDdiSetFlipQueueLogBuffer) 之前。 當翻轉佇列沒有任何未完成的要求時,允許 OS 終結翻轉佇列記錄緩衝區。 在此情況下,它會在下一個 DxgkDdiSetVidPnSourceAddress 呼叫之前提供新的記錄指標。 翻轉佇列記錄是迴圈的。 寫入 [NumberOfEntries-1] 項目之後,下一個記錄專案會是 [0]。
完成一批佇列翻轉之後,KMD 必須保證已完成翻轉的翻轉佇列記錄最早會在這兩個時間點中更新:
- 需要引發中斷之翻轉的 VSync 中斷處理程式。
- 為了回應來自OS的明確 DxgkDdiUpdateFlipQueueLog 要求。
翻轉佇列記錄 DIS
已新增下列翻轉佇列記錄相關回呼和相關聯的結構:
KMD 會在 DRIVER_INITIALIZATION_DATA 中提供其函式的指標。
VSync 中斷結構更新
已對 DXGKARGCB_NOTIFY_INTERRUPT_DATA 結構進行下列變更,以實作硬體翻轉佇列模型的 VSync 中斷:
- DXGK_INTERRUPT_CRTC_VSYNC_WITH_MULTIPLANE_OVERLAY3列舉值已新增為 InterruptType。
- CrtcVSyncWithMultiPlaneOverlay3 結構已新增至聯集。 CrtcVSyncWithMultiPlaneOverlay3 的語意類似於現有的 CrtcVSyncWithMultiPlaneOverlay2 結構,不同之處在於,CrtcVSyncWithMultiPlaneOverlay3.pMultiPlaneOverlayVSyncInfo 指向先前從翻轉佇列記錄中未回報的 PresentId 的範圍。
- 已為 CrtcVSyncWithMultiPlaneOverlay3 的 pMultiPlaneOverlayVSyncInfo 成員新增DXGK_MULTIPLANE_OVERLAY_VSYNC_INFO3結構。
再次使用基本硬體翻轉佇列範例圖表:
假設 FirstFreeFlipQueueLogEntryIndex 在提交翻轉 N 時設定為 40,然後 完成 N、 N+1、 N+2 簡報。
在單平面設定完成三個 PresentIds N、 N+1 和 N+2 之後,v2、v3、v4、KMD 在其翻轉佇列記錄緩衝區中寫入了三個新專案,其索引為 40、41 和 42。 KMD 會報告 CrtcVSyncWithMultiPlaneOverlay3 結構中的 FirstFreeFlipQueueLogEntryIndex 值 43。 OS 觀察到 FirstFreeFlipQueueLogEntryIndex 從 40 變更為 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 所收到的旗標、 持續時間和時間戳的組合。
撕裂和非Tearing 翻轉語意
啟用硬體翻轉佇列時,撕裂翻轉的語意在概念上相同。 達到 TargetFlipTime 之後,KMD 應該提交翻轉以顯示,同時仍接受 FlipImmediate、FlipImmediateNoTearing 和 FlipOnNextVSync 等旗標。 換句話說,KMD 的行為應該就像操作系統以相同的翻轉旗標和參數在 TargetFlipTime 提交翻轉。
例如,如果 FlipOnNextVSync 設定為 1,且 TargetFlipTime 位於框架中間,則翻轉應該只會顯示在下一個 VSync 上。
FlipOverwrite 支援和硬體翻轉佇列
硬體翻轉佇列是DXGK_DRIVERCAPS中 MaxQueuedMultiPlaneOverlayFlipVSync 值所控制之翻轉覆寫功能的嚴格超集。
因此,如果驅動程式選擇加入硬體翻轉佇列,則 OS 會忽略 MaxQueuedMultiPlaneOverlayFlipVSync 值,方法是將 MaxHwQueuedFlips 設定為大於 1 的值。
具有過期 TargetFlipTime 的多個翻轉
當指定 MPO 平面有多個已過期 TargetFlipTime 的佇列翻轉時,硬體顯示佇列必須挑選最近佇列的過期翻轉,並提交它以顯示。 其餘過期的翻轉應該視為已取消,而對應的翻轉佇列記錄項目應該包含DXGK_HWFLIPQUEUE_TIMESTAMP_CANCELLED為 PresentTimestamp 值。
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 功能出現時的對應間隔
虛擬重新整理速率功能可能會暫時將顯示器重新整理速率提升為目前重新整理速率的整數倍數(也就是說,24 Hz 可以提升至144 Hz或192 Hz)。 對於能夠支援此提升的裝置,上一節中的公式會修改為使用目前重新整理速率中最快的倍數:
TargetFlipTime = PreviousFlipStartVSyncTime + (PreviousFlipPresentInterval * FixedRefreshRate) - (FastestRefreshRate / 2)
重新整理速率變更為非多函式時的對應間隔
當重新整理速率變更為目前重新整理速率的非多餘時(例如,從 24 Hz 變更為 60 Hz),OS 必須檢查佇列翻轉,以查看其計算目標時間是否仍然對新的重新整理速率有效。 如果需要變更目標翻轉時間,OS 會取消佇列翻轉,並使用新計算的目標翻轉時間重新排入佇列。