Skip to main content
XDXR 是 XBOX 在 XBOX Series X|S 上對 DirectX Raytracing (DXR) API 的實作。除了可呼叫著色器之外 (截至 2019 年 11 月),XDXR 所提供的功能是 Windows 10 2019 年 11 月更新版 Windows PC 上 DXR API 所提供功能的超集。 本主題假設您熟悉 DXR。強烈建議您閱讀 DXR 文件與 Windows DXR 規格。

與 Windows 上 DXR 的差異

建立全域根簽章時,必須在根簽章描述上設定額外的旗標:D3D12XBOX_ROOT_SIGNATURE_FLAG_RAYTRACING。此旗標目前無法在以高階著色器語言 (HLSL) 指定的根簽章中設定,必須在根簽章序列化之前於程式碼中設定。 XDXR 並未完整支援 DXR 1.1 RayQuery.TraceRayInline() 功能,不過我們提供一個模擬 RayQuery API 的標頭檔 (XDXRStandaloneTraverse),對於大部分 RayQuery 程式碼應能提供非常簡單的移植體驗。具體差異請參閱 XDXR 獨立周遊。 XDXR 目前不支援 RAY_FLAG_SKIP_TRIANGLES、RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES 或 D3D12_RAYTRACING_PIPELINE_FLAGS 系統。未來可能會有所修訂。目前在 XBOX 上,批次 TLAS 建置可以非常快速,在此情況下建置個別的 TLAS 會比略過節點提供更好的周遊效能。 XDXR 支援數個延伸功能,可直接從 BVH 或周遊查詢狀態,而不需要使用承載資料來儲存。 若要使用這些延伸功能,請在光線追蹤著色器的頂端預先宣告下列一或多個函式。

XDXR 的設計

從高層次來看,XDXR 的實作可視為分成兩個部分:周遊核心 (Traversal Core) 與「排程器」(Scheduler)。

周遊核心

周遊核心是 XDXR 的包圍體階層 (BVH) 周遊實作。它負責處理周遊以及高層次的決策,例如要呼叫哪些著色器 (例如最近命中與任意命中著色器)。它不處理實際呼叫著色器的機制,那是排程器的責任。 XDXR 使用 BVH4 表示法來儲存其加速結構。雖然也可以選擇其他 BVH 格式,但此格式符合 XBOX Series X|S 用於執行光線/軸對齊包圍盒 (AABB) 交集測試的自訂硬體所使用的格式。如需詳細資訊,請參閱光線追蹤硬體設計。

周遊

XDXR 目前未實作任何形式的光線重新封裝、排序或重新排列。從叫用光線產生著色器的那一刻起,任何未主動追蹤光線的執行緒都是 wave 中的「非作用中通道」,浪費了執行有用工作的機會。從概念上來說,光線是在指定的執行緒上產生的。後續對任何著色器的叫用或遞迴光線都存在於同一個執行緒上。如果光線產生著色器在 wave 的通道 0 上產生兩條光線,而在其他所有通道上沒有產生光線,則執行緒 0 必須依序完成其兩條光線,而其他所有執行緒則保持非作用中狀態。 XDXR 目前公開兩種 BVH 周遊演算法。預設演算法稱為「發散」(Divergent) 周遊,是最通用的解決方案,適合光澤反射等發散的工作負載。對於 TraceRayInline(),對應的標頭為 XDXRStandaloneTraverseShortStack.hlsli。對於陰影光線或非光澤反射等高度一致的工作負載,2022 年 6 月 GDK 提供了新的「混合」(Hybrid) 周遊演算法。此演算法使用純量分支執行 TLAS 周遊,只有在進入 BLAS 時才會發散。混合周遊可能會在某些內容與光線追蹤工作負載上大幅提升效能。 若要啟用「混合」周遊,請將 XBOX_RAY_FLAG_COHERENT_RAYS_HINT 加入 DXR 1.0 TraceRay() 光線旗標中。光線旗標與 TLAS 指標必須一致 (uniform) 才能啟用此周遊類型。對於 TraceRayInline(),對應的標頭為 XDXRStandaloneTraverseHT.hlsli。

排程器

排程器負責驅動 DXR 的「主迴圈」。DXR 的設計需要支援透過指標進行函式呼叫 (也稱為_間接呼叫_),這是通常與 GPU 架構無關的概念。未來,在 DXR/XDXR 之外進行函式呼叫的能力將會公開,以供更一般的用途使用。 在考量如何最佳化使用 XDXR 時,務必考量過度依賴重複函式呼叫對效能的影響。呼叫 TraceRay 與其他 DXR 著色器時,必須在跳至新的程式碼片段之前,儲存並重新載入每個執行緒的暫存器狀態。將每個執行緒/光線的狀態儲存到記憶體中並在稍後重新載入,每次發生時都會耗用相當大量的頻寬。 在較高的解析度下,即使每條光線只需要寫入和讀取一次其暫存器狀態,如果處理不當,也可能耗用數百 MB 的記憶體。儲存/還原光線狀態的頻寬需求,很快就會遠超過實際讀取 BVH 與相關材質資訊 (例如紋理) 的成本。光線追蹤的總記憶體存取必須包括讀取 BVH、紋理、索引、頂點,寫入一些以無序存取檢視 (UAV) 為基礎的輸出,以及讀取/寫入光線狀態以進行函式呼叫。基於這些原因,我們建議盡可能避免遞迴與任意命中著色器。

著色器編譯

著色器編譯為機器碼的作業是以集合為單位進行的。所有可完全解析的函式都會編譯為機器碼,並在排程器中透過指標使用。周遊核心 (周遊函式) 只會根據最大屬性大小以及是否存在交集著色器而視需要編譯。這有助於減少記憶體大小、加快編譯速度,並改善指令快取的使用率。 可以預先編譯著色器,但預先編譯的光線追蹤著色器只能搭配相符版本的排程器與周遊核心使用。這是因為 XDXR 使用特定的函式呼叫慣例,而此慣例隨時可能變更。我們對 XBOX 的相關建議仍在考量中。

DispatchRays

考量到執行 XDXR 排程器所需的記憶體量 (在某些情況下,每條光線需要 1 KB!),並暫時假設每條光線的暫存大小是唯一限制佔用率的因素,則為了維持佔用率 1,我們需要在 XBOX Series X 上執行大約 3,584 個通道。任何時候,每批光線都需要使用數 MB 的暫存記憶體。 使用該記憶體的一個明顯選擇是系統暫存。然而,它在 XBOX One 上的用途有限,因為重新設定暫存大小需要完整排清。因此,非同步計算管道不支援它。著色器處理器內插器 (SPI) 不支援一個以上的暫存檢視,所以這個方法行不通。 因此,DispatchRays 會使用多個分派來處理整組光線。驅動程式使用自訂暫存緩衝區,在小型 DispatchRays 分派之間循環使用。可用的暫存大小將決定並行分派的數量,進而決定光線追蹤效能。系統會使用一般柵欄,防止分派覆寫其他已在執行中的 wave 正在使用的自訂暫存。 DispatchRaysX 允許指定自訂暫存緩衝區。在非同步計算上執行光線追蹤工作負載時,這是必要的。請注意,內嵌的 XDXR 獨立周遊不需要暫存,因此可以作為一般計算著色器在非同步計算上執行,無需特殊處理。

另請參閱

光線追蹤 (與 DXR) 概觀
Last modified on October 6, 2026