簡介
圖形虛擬記憶體系統已針對 Microsoft Game Development Kit (GDK) 重新建置。雖然內部機制全部都是新的,但整體功能集與 XBOX One ERA 作業系統相比並無太大差異。功能集包括:- 圖形記憶體的統一 CPU 與 GPU 虛擬位址空間,位於虛擬位址空間較低的 1,024 GB 內,其中最低的 4 GB 保留給需要 32 位元位址的特定圖形配置。
- 圖形的原生 64 KB 分頁大小,以及較大的 2 MB 分頁大小。
- 在記憶體配置時指定的圖形屬性,包括讀取/寫入、執行,以及 GPU 快取一致性。
- XMemAlloc,這是一個彈性且快速的圖形記憶體使用者模式堆積,包括攔截來自各種 XBOX 遊戲程式庫之配置的功能。
- 遊戲可存取的實體分頁配置與對應 API。
- 透過 Direct3D 12 並排資源和分頁對應延伸 API,直接以 GPU 存取 GPU 分頁對應。
- 可由遊戲控制的 GPU 分頁表記憶體配置大小,此記憶體會在初始化時配置 (不會在執行階段配置)。
初始化圖形記憶體系統
在配置圖形記憶體之前,遊戲必須先在核心中初始化圖形記憶體系統。這是 Microsoft Game Development Kit (GDK) 的新要求。初始化圖形記憶體系統最簡單的方式,是透過 D3D12CreateDevice API 建立 Direct3D 12 裝置。如果遊戲必須在建立 Direct3D 12 裝置之前配置或保留圖形記憶體,也可以使用 D3D12ConfigureVirtualMemoryX (XBOX Series X|S)/D3DConfigureVirtualMemory (XBOX One) API 來初始化圖形記憶體系統。建立 Direct3D 12 裝置相當於以預設參數呼叫 D3D12ConfigureVirtualMemoryX。用於配置圖形記憶體的新旗標
新的遊戲 API XMemVirtualAlloc 已推出,用來取代 XBOX One ERA 中的延伸 VirtualAlloc。Microsoft Game Development Kit (GDK) 中的 VirtualAlloc 現在僅限於「標準」平台行為,與桌面版 Windows 相同。 標準的 VirtualFree API 可用來釋放和/或解除認可以 XMemVirtualAlloc 配置的記憶體。新增的 XMemVirtualQuery API 可擷取指定虛擬位址的完整 CPU 和 GPU 保護旗標集。 XMemVirtualAlloc 採用新的 XMem 旗標組合,用以表示對圖形和/或工具記憶體的要求。XBOX One ERA 中 VirtualAlloc 的配置旗標 MEM_GRAPHICS,相當於 XMemVirtualAlloc 的 XMem 旗標 XMEM_GRAPHICS。 新旗標 XMEM_GRAPHICS_32BIT_ADDRESS 與 XMEM_GRAPHICS 結合使用時,會配置圖形記憶體,但將自動指派的虛擬位址限制在 2 GB-4 GB 範圍內。若沒有 XMEM_GRAPHICS_32BIT_ADDRESS 旗標,自動指派的虛擬位址會高於 4 GB,且低於圖形分頁表所涵蓋範圍的結尾 (預設為 159 GB)。圖形分頁表的結尾虛擬位址由專用於圖形分頁表的記憶體量所定義,並可在第一次圖形配置之前使用 D3D12ConfigureVirtualMemoryX API 加以調整。 分頁大小旗標的語意也已變更。XBOX One ERA 使用 MEM_LARGE_PAGES 表示 64 KB 分頁,並使用 MEM_4MB_PAGES 表示 4 MB 分頁。Microsoft Game Development Kit (GDK) 現在使用 MEM_64K_PAGES 表示 64 KB 分頁,並使用 MEM_2MB_PAGES 表示 2 MB 分頁。請注意,使用 MEM_LARGE_PAGES 的現有遊戲程式碼必須謹慎且徹底地更新為使用 MEM_64K_PAGES。Microsoft Game Development Kit (GDK) 不支援 4 MB 分頁。 最後,圖形的分頁保護旗標也已變更。XBOX One ERA 的 PAGE_GPU_* 旗標已由 PAGE_GRAPHICS_* 列舉和 PAGE_GRAPHICS_COHERENT 旗標取代,以更符合現有的 CPU 分頁保護模式。所有透過 XMemGraphics 進行的圖形配置,都必須僅包含下列其中一個保護旗標:- PAGE_GRAPHICS_NOACCESS
- PAGE_GRAPHICS_READONLY
- PAGE_GRAPHICS_READWRITE
- PAGE_GRAPHICS_EXECUTE
- PAGE_GRAPHICS_EXECUTE_READ
- PAGE_GRAPHICS_EXECUTE_READWRITE
XALLOC_MEMTYPE_GRAPHICS_WRITECOMBINE | PAGE_READWRITE | PAGE_WRITECOMBINE | PAGE_READWRITE | PAGE_WRITECOMBINE | PAGE_GRAPHICS_READWRITE | PAGE_READWRITE | PAGE_WRITECOMBINE | PAGE_GRAPHICS_READWRITE | | “Onion” 記憶體:CPU 快取且 GPU 一致性 | XALLOC_MEMTYPE_GRAPHICS_CACHEABLE | PAGE_READWRITE | PAGE_GPU_COHERENT | PAGE_READWRITE | PAGE_GRAPHICS_COHERENT | PAGE_GRAPHICS_READWRITE | PAGE_READWRITE | PAGE_GRAPHICS_COHERENT | PAGE_GRAPHICS_READWRITE | | “Garlic” 命令緩衝區 | XALLOC_MEMTYPE_GRAPHICS_COMMAND_BUFFER_WRITECOMBINE | PAGE_READWRITE | PAGE_WRITECOMBINE | PAGE_GPU_EXECUTE | PAGE_READWRITE | PAGE_WRITECOMBINE | PAGE_GRAPHICS_EXECUTE_READWRITE | PAGE_READWRITE | PAGE_WRITECOMBINE | PAGE_GRAPHICS_EXECUTE_READWRITE | PAGE_GRAPHICS_NOCACHE | | “Onion” 命令緩衝區 | XALLOC_MEMTYPE_GRAPHICS_COMMAND_BUFFER_CACHEABLE | PAGE_READWRITE | PAGE_GPU_EXECUTE | PAGE_GPU_COHERENT | PAGE_READWRITE | PAGE_GRAPHICS_EXECUTE_READWRITE | PAGE_GRAPHICS_COHERENT | PAGE_READWRITE | PAGE_GRAPHICS_EXECUTE_READWRITE | PAGE_GRAPHICS_NOCACHE | PAGE_GRAPHICS_COHERENT | | “Cached garlic” 記憶體:CPU 快取、GPU 非一致性且唯讀 | XALLOC_MEMTYPE_GRAPHICS_CACHEABLE_NONCOHERENT_GPU_READONLY | PAGE_READWRITE | PAGE_GPU_READONLY | PAGE_READWRITE | PAGE_GRAPHICS_READONLY | PAGE_READWRITE | PAGE_GRAPHICS_READONLY | | 柵欄回寫記憶體:CPU 快取且 GPU 一致性 | XALLOC_MEMTYPE_GRAPHICS_GPU_UNCACHED | 不適用 (使用 XALLOC_MEMTYPE_GRAPHICS_CACHEABLE) | PAGE_READWRITE | PAGE_GRAPHICS_COHERENT | PAGE_GRAPHICS_READWRITE | PAGE_READWRITE | PAGE_GRAPHICS_COHERENT | PAGE_GRAPHICS_NOCACHE | PAGE_GRAPHICS_READWRITE |
適用於 Microsoft Game Development Kit (GDK) 的 XMemAlloc
XMemAlloc 使用者模式記憶體堆積已以最少的變更移植到 Microsoft Game Development Kit (GDK)。它現在位於自己的 DLL (xmem.dll) 和連結程式庫 (xmem.lib) 中。現有的 XMemAlloc API,包括 XMemAlloc、XMemFree 和 XMemSetAllocationHooks,仍然存在,且運作方式與在 XBOX One ERA 中相同。 傳遞給 XMemAlloc 和 XMemFree 的 XALLOC_ATTRIBUTES 結構中新增了 Address32BitMapping 旗標。此新旗標表示呼叫端想要配置記憶體,且該配置必須具有 32 位元位址。Microsoft Game Development Kit (GDK) Direct3D 12 使用者模式圖形驅動程式在建立特定記憶體配置時會使用此旗標,包括描述元堆積和管線狀態物件記憶體。這些配置存留期長,且一律以 64 KB 分頁對齊,因此不需要進行堆積管理。相反地,這些配置要求可以搭配 XMEM_GRAPHICS_32BIT_ADDRESS 旗標傳遞給 XMemVirtualAlloc。 XBOX One ERA 中的 Direct3D 12 圖形驅動程式在背景使用複雜且成本高昂的機制,將任意遊戲配置重新對應到 32 位元位址空間,使 XMemAlloc 實作和遊戲都不知道需要 32 位元位址。Microsoft Game Development Kit (GDK) 圖形驅動程式已放棄這套複雜的系統,改採更簡單、更快速的方法,明確地向遊戲和 XMemAlloc 實作傳達需要 32 位元配置。Direct3D 12.X 描述元堆積記憶體變更
XBOX One ERA 上的 Direct3D 12.X 圖形驅動程式會為所有 GPU 可見的描述元堆積建立 CPU 快取且唯讀的第二個記憶體別名。在 CPU 上讀取描述元的程式碼會使用此快取的唯讀別名來提升 CPU 讀取效能。Microsoft Game Development Kit (GDK) 上已不再提供此第二個記憶體別名,因此任何從 GPU 可見描述元堆積進行的 CPU 讀取,都是從寫入合併記憶體進行的非快取 CPU 讀取。請注意,轉譯目標和深度樣板描述元堆積 (D3D12_DESCRIPTOR_HEAP_TYPE_RTV 和 D3D12_DESCRIPTOR_HEAP_TYPE_DSV) 一律會建立為 CPU 快取記憶體,不論是否建立為 GPU 可見。XBOX One 和 XBOX Series X|S 上對 “Cached Garlic” 記憶體的支援
在 XBOX One 上,Microsoft Game Development Kit (GDK) 不再支援建立 CPU 快取且唯讀、GPU 非一致性且可讀寫的記憶體對應。此不允許組合所使用的 Microsoft Game Development Kit (GDK) 分頁保護旗標為PAGE_READONLY | PAGE_GRAPHICS_READWRITE。
在 XBOX Series X|S 上,Microsoft Game Development Kit (GDK) 支援建立全部 3 種快取、非一致性記憶體對應。這 3 種類型分別是 CPU 可讀寫且 GPU 唯讀、CPU 唯讀且 GPU 可讀寫,以及 CPU 可讀寫且 GPU 可讀寫。使用這些類型的圖形記憶體時,必須特別小心,以避免因 CPU 和 GPU 的非一致性快取而導致記憶體損毀。
使用 cached garlic 記憶體時,請牢記下列規則:
- 在 CPU 或 GPU 上讀取或寫入 cached garlic 記憶體之前,請排清快取。
- 在 CPU 或 GPU 上完成對 cached garlic 記憶體的寫入之後,請排清快取。
- 使用同步處理基本類型來控制對 cached garlic 記憶體的獨佔寫入存取。避免多個用戶端同時寫入。
- 考量讀取/寫入存取模式時,請一次檢視整個 64 位元組的快取行,因為該大小是載入至 CPU 和 GPU 快取並寫回的記憶體單位。無法一律確保 CPU 或 GPU 會產生部分快取行寫入,特別是對於快取記憶體。
