(Direct3D 9) 遺失的裝置

Direct3D 裝置可能在操作狀態或遺失狀態。 操作狀態是一般裝置狀態,裝置如預期般執行和呈現所有轉譯。 該裝置會轉換成遺失狀態,例如在全螢幕應用程式中遺失鍵盤焦點,會導致不可能轉譯。 遺失狀態的特性所有轉譯操作無聲息地失敗,這表示轉譯方法可傳回成功碼,即使所有的轉譯作業失敗。 在此情況下, IDirect3DDevice9::P resent會傳回錯誤碼D3DERR_DEVICELOST。

經過設計,未指定可能會導致裝置遺失的整套案例。 一些常見的範例包括焦點,例如當使用者按下 ALT + TAB 或當初始化系統對話方塊時。 裝置也可能因電源管理事件而遺失,或在另一個應用程式繼續全螢幕作業時遺失。 此外, 來自 IDirect3DDevice9::Reset 的任何失敗都會讓裝置進入遺失狀態。

所有衍生自IUnknown的方法,保證在裝置遺失之後運作。 遺失裝置之後,每項功能通常具有以下三個選項︰

  • 失敗並出現D3DERR_DEVICELOST - 這表示應用程式必須辨識裝置已遺失,讓應用程式識別出未如預期般發生的專案。
  • 以無訊息方式失敗、傳回S_OK或任何其他傳回碼 - 如果函式以無訊息方式失敗,應用程式通常無法區分「成功」和「無訊息失敗」的結果。
  • 函式會傳回傳回碼。
Direct3D 9 與 Direct3D 9Ex 之間的差異:
Direct3D 9 裝置會傳回D3DERR_DEVICELOST。 一旦從 IDirect3DDevice9::P resent傳回,模擬行為就不會再運作,而且所有未來的呼叫都會失敗,直到裝置成功重設為止。
Direct3D 9Ex 裝置永遠不會傳回D3DERR_DEVICELOST,但可以傳回新的狀態訊息, (查看 裝置行為變更) 。

 

回應遺失裝置

遺失的裝置必須在重設後重新建立資源 (包括視訊記憶體資源)。 如果遺失裝置,應用程式會查詢裝置,查看是否可以還原到運作狀態。 若否,應用程式會等到裝置還原。

如果可以還原裝置,應用程式會藉由破壞所有影片記憶體資源和任何交換鏈來準備裝置。 然後,應用程式會呼叫 IDirect3DDevice9::Reset 方法。 Reset 是唯一在裝置遺失時生效的方法,也是應用程式可以將裝置從遺失變更為操作狀態的唯一方法。 除非應用程式釋放D3DPOOL_DEFAULT中配置的所有資源,否則重設將會失敗,包括 IDirect3DDevice9::CreateRenderTargetIDirect3DDevice9::CreateDepthStencilSurface 方法所建立的資源。

大部分的 Direct3D 高頻呼叫不會傳回是否裝置已遺失的任何資訊。 應用程式可以繼續呼叫轉譯方法,例如 IDirect3DDevice9::D rawPrimitive,而不會收到遺失裝置的通知。 內部將會捨棄這些作業,直到裝置重設為操作狀態。

應用程式可以藉由查詢 IDirect3DDevice9::TestCo可Level 方法的傳回值,判斷遇到遺失裝置時該怎麼辦。

鎖定作業

在內部 Direct3D 運作以確保遺失裝置之後成功鎖定作業。 不過,它並不保證鎖定作業期間影片記憶體資源的資料是準確的。 它保證不傳回錯誤碼。 這可讓應用程式寫入,不需擔心鎖定作業期間遺失裝置。

資源

資源可能會消耗視訊記憶體。 遺失的裝置與介面卡擁有的視訊記憶體中斷連線,所以不保證遺失裝置時的視訊記憶體配置。 因此,所有資源建立方法都會藉由傳回D3D_OK來實作成功,但實際上只會配置虛擬系統記憶體。 必須先破壞任何視訊記憶體資源,再重新調整裝置大小,如此就不會有過度配置視訊記憶體的問題。 這些虛擬表面允許鎖定和複製作業正常運作,直到應用程式呼叫 IDirect3DDevice9::P resent ,併發現裝置已遺失為止。

必須發佈所有的視訊記憶體,才能將裝置從遺失狀態重設為可操作狀態。 這表示應用程式應該釋放使用 IDirect3DDevice9::CreateAdditionalSwapChain 建立的任何交換鏈結,以及放置在D3DPOOL_DEFAULT記憶體類別中的任何資源。 應用程式不需要釋放D3DPOOL_MANAGED或D3DPOOL_SYSTEMMEM記憶體類別中的資源。 在轉換到操作狀態時,其他狀態資料會自動損壞。

您可以使用單一程式碼路徑開發應用程式,以回應裝置遺失。 此程式碼路徑如果和初始啟動裝置的程式碼路徑不相同,也會很類似。

擷取的資料

Direct3D 可讓應用程式使用 IDirect3DDevice9::ValidateDevice,針對硬體的單一傳遞轉譯驗證紋理和轉譯狀態。 這個方法通常會在應用程式初始化期間叫用,如果裝置遺失,則會傳回D3DERR_DEVICELOST。

Direct3D 也可讓應用程式複製已產生或先前從視訊記憶體資源寫入影像至非揮發性系統記憶體資源。 這類傳輸的來源影像可能隨時會遺失,因此 Direct3D 允許在裝置遺失讓此類複製作業失敗。

關於非同步查詢,如果指定 FLUSH 旗標, IDirect3DQuery9::GetData 會傳回D3DERR_DEVICELOST,以便向應用程式指出 IDirect3DQuery9::GetData 永遠不會傳回S_OK。

複製作業 IDirect3DDevice9::GetFrontBufferData可能會因D3DERR_DEVICELOST而失敗,因為裝置遺失時沒有主要介面。 IDirect3DDevice9::CreateAdditionalSwapChain 也可以失敗,D3DERR_DEVICELOST,因為當裝置遺失時無法建立背景緩衝區。 請注意,這些情況是 IDirect3DDevice9::P resentIDirect3DDevice9::TestCoultLevelIDirect3DDevice9::Reset 方法以外的唯一D3DERR_DEVICELOST實例。

可程式化著色器

在 Direct3D 9 中,頂點著色器和圖元著色器不需要在重設之後重新建立。 系統會記住它們。 在舊版 DirectX 中,遺失的裝置需要重新建立著色器。

Direct3D 裝置