記憶體管理原則
Direct3D 12 的記憶體管理員可能會因為支援的所有不同層級、UMA 或離散 (非 UMA) 介面卡,以及 GPU 介面卡之間的架構差異相當多,而變得非常複雜。
本節所述的 Direct3D 12 記憶體管理建議策略是「分類、預算和資料流程」。
資源類型
「認可資源」的基本概念 (在受控實體記憶體中初始化的虛擬和實體位址空間,) 自 Direct3D 9 起就已周遭,不過虛擬定址 (VA) 和實體定址可以在 Direct3D 12 中分開,讓應用程式仔細管理實體記憶體。
除了已認可的資源,Direct3D 12 的堆積建構還啟用兩種其他類型的資源:「放置」和「保留」。 在 Direct3D 11 中,「保留」資源稱為「並排資源」。
保留的資源與放置的資源不同,因為保留的資源有自己的唯一 GPU 虛擬位址空間。 這允許預先配置大量的 VA 空間,然後讓 VA 頁面稍後對應至堆積的特定區段,而應用程式會即時重新設定相片順序。 VA 空間是連續的,而且可以疏鬆地對應至 。
保留的資源可以透過 API 呼叫來參考堆積中的區域,例如 UpdateTileMappings ,而且可以透過即時更新頁面表讓應用程式駐留。 當 VA 範圍對應至 Null 或非常駐堆積時,該部分的資源會被視為非常駐。 當 VA 範圍對應至常駐堆積時,該部分的資源會被視為「常駐」。 堆積會在建立時存在。
放置的資源是更簡單的設計,只是堆積特定區域的指標 (例如,5Mb 堆積中紋理的 1Mb 區域) 。 別名屏障可讓您使用重迭放置的資源 (參考 CreatePlacedResource 和 ResourceBarrier) 。
所有 Direct3D 12 硬體上都無法使用保留的資源,而放置的資源是合理的後援,不過放置的資源必須連續且不能部分駐留。
記憶體預算
在 Direct3D 12 中,當您配置堆積時,您要建立已認可資源的實體記憶體層面。 Direct3D 12 提供更明確的記憶體區段選擇, (視訊與系統記憶體) 之間選擇。 UMA 介面卡只有單一記憶體區段,系統記憶體。
GPU 不支援分頁錯誤,因此開發人員必須注意到它們不會過度認可,特別是系統說只有 1Gb 的系統記憶體。 如果應用程式過度認可,則 OS 會依對實體記憶體的需求,使用更粗略的處理常式排程。 排程器會凍結前景進程,而且基本上會將其中一些進程分頁,以便分頁到想要執行的背景進程。 可用的實體記憶體可能會根據使用者在背景 (中執行的動作而有很大的差異,例如執行瀏覽器或觀看視訊) 。
記憶體預算的 API 是 QueryVideoMemoryInfo。 針對離散介面卡「本機」是視訊記憶體,「非本機」是系統記憶體。 對於非本機的 UMA 配接器,一律為零。 其中一個設計問題是您的引擎會管理這兩個預算,還是只管理本機預算。 只管理本機預算比較簡單,但有一些注意事項;例如,假設本機預算上限為 1Gb,則所有堆積都會來自 UMA 系統中的 1Gb,而且系統記憶體 (沒有溢位,因為沒有任何) 。
由於應用程式的 Direct3D11 受控記憶體,未使用的資源基本上會分頁。
選擇最適當的資源維度。 請考慮資源大小是否適合應用程式實際執行的情況。 有些使用者可能會在視窗中執行應用程式,或螢幕解析度為 800x600。
分類策略
若要在記憶體系結案例中有效地管理資源,請考慮將資源分類為下列各項:
分類 | 範例 | 物件和 API 功能 | 管理注意事項 |
---|---|---|---|
重大 | 遊戲 UI | 命令配置器、命令佇列、查詢堆積、資源和資源堆積。 | 這些元素應該在不可分頁/永遠認可的記憶體中。 |
調整/選擇性 | 層級特定的模型和紋理、交換鏈結、空箱、第一人稱玩家字元模型 | 資源和堆積。 已認可的資源,但放置和保留的資源可能也會正常運作。 | 將記憶體落地預算整合到轉譯演算法中。 選擇適當的可用詳細資料層級,並重新評估每一畫面格少於一次。 技術包括使用可變大小的資源和交換鏈結調整。 |
重複使用的資源 | 陰影緩衝區、延後轉譯資源、後置處理資源、光來源資料快取 | 資源和堆積。 重迭的資源位於堆積和別名屏障上。 | 重複使用框架內的大型資源或堆積區域,以縮減整個框架的需求。 使用內部框架記憶體重複使用的技術。 在 Direct3D 11 中,應用程式只能重複使用具有相同類型且可能夠大維度的資源。 Direct3D 12 堆積允許重迭的資源更容易重複使用。 |
串流資源 | 地形、開放世界紋理和幾何 | 資源和堆積。 自由執行緒建立、背景 CPU 執行緒和背景複製命令佇列和清單。 | 部分落地,通常是使用檢視-frustum 或以距離為基礎的評估) ,以及重新評估落地需要每個畫面格的可見度 (。 當 GPU 配接器支援堆積內的保留資源時,可以使用每個磚的部分落地管理和畫面間重複使用的技術。 使用使用框架間記憶體重複使用的技術,可以完成部分子資源落地,但較不理想。 具有堆積的放置資源應該可以加快回收速度,但認可的資源可以做為後援使用。 |
對於大部分的工作,應用程式更需要串流資源,它們會利用放置和保留的資源越多,這會將這四個分類之間的記憶體重複使用最大化。 應用程式串流越多,其預算就越高,並排定頻寬的優先順序。
一般而言,Direct3D 12 圖形引擎必須採用更多元且動態的預算,而且比過去更嚴格。 最佳應用程式會將這四個類別都放在提供給程式的預算中,將遊戲從背景行動裝置應用程式調整為全螢幕離散預算。 但是,許多應用程式可能從太多重要類別類型的資源開始而困難。 Direct3D 11 可匿名建立資源並佔用重大狀態,而不會影響效能。 不過,針對 Direct3D 12,開發人員必須仔細搜尋整個引擎和中介軟體中隨機建立的資源,並將其重新指派給其他類別的其中一個。
其他問題區域是中介軟體元件、使用者控制項和畫面內部串流。 中介軟體元件可能不會公開至預算,也不需要緊密搭配運作。 中介軟體元件可能會將功能公開為轉譯技術;和 應用程式可能依賴公開中介軟體和引擎設定。 開發人員可以依賴 Direct3D 11 來執行分頁,並達到正確的畫面播放速率。 在某些情況下,Direct3D 11 應用程式可能已在每一個畫面中分頁資源內容;而且導致使用者可接受的畫面播放速率。 大部分引擎只會將資源資料串流為背景活動,其中沒有適當後援至高優先順序的畫面內串流。 要求引擎實作,這可藉由移至 Direct3D 12 來獲得其所尋求的一些 CPU 額外負荷。 引擎開發人員可以考慮將其框架分階段,以提供更多機會供重複使用的資源;而且可能與中介軟體廠商合作,以支援放置的資源和堆積,以便重複使用內部畫面記憶體。