跳轉到主要內容
DirectX 著色器編譯器 (DXCompiler 或 DXC) 是適用於 Windows 與 XBOX 的新著色器編譯器。 在 Windows 上,光線追蹤與其他新功能已經需要 DXC。今後,DXC 將是啟用許多其他新功能的受支援途徑,包括正在積極開發中之未來遊戲平台上提供的功能。我們將在未來的版本中新增更多 XBOX 內建函式、新的著色器模型支援,以及許多其他功能與效能改進。 較舊的 D3D 著色器編譯器 (D3DCompiler 或 FXC) 已淘汰且不再受支援。

HLSL 2021

自 2023 年 10 月 GDK 起,DXC 預設使用 HLSL 2021 語言。HLSL 2021 新增了對各種 C++ 樣式功能的支援:
  • 範本函式與結構
  • 結構元素上的位元欄位
  • 運算子多載
  • C++ 樣式的函式多載
  • 純量的邏輯運算短路
如需詳細資訊,請參閱 HLSL 2021 與 HLSL 2021 移轉指南。 若要使用先前的預設語言 HLSL 2018,請將 -HV 2018 傳遞給編譯器。 GitHub 上目前的問題清單位於 HLSL 2021 問題標籤底下。 歡迎在 GitHub 上提出錯誤,或透過 AskHLSL@microsoft.com 與我們聯絡,提供意見反應與問題。

開發中

XBOX 的 DXC 目前正在積極開發中。我們將在未來的版本中新增簡化的編譯器 .dll 介面、更多 XBOX 內建函式、新的著色器模型支援,以及許多其他功能與效能改進。 您可以透過 AskHLSL@microsoft.com 與小組聯絡。

著色器編譯器說明

  • 使用 DXC:如何使用編譯器命令列介面 (dxc) 與 .dll 介面 (dxcompiler_x.dll)
  • FXC 至 DXC 移植指南:將著色器移植至 DXC 時的一些秘訣與技巧

XBOX 特有功能

XBOX 的 DXC 支援許多 Windows 上無法使用的特殊定義與內建函式。如需詳細資訊,請參閱下列內容:

預先編譯

在 XBOX 上,DXC 編譯器可以將 HLSL 一路編譯為 XBOX GPU 的最終指令集架構 (ISA) 指令。這可讓遊戲避免在執行階段從 DXIL 編譯為 ISA 指令的昂貴步驟。我們將此完整編譯步驟稱為「預先編譯」,因為它會離線 (在開發電腦上) 而非線上 (在 XBOX 主機上) 將著色器編譯為 ISA。 有多種定義可用於控制預先編譯。在 XBOX 上,基本上有 3 種編譯著色器的方式。 A. 離線預先編譯並移除 DXIL (/D__XBOX_STRIP_DXIL=1)
B. 離線預先編譯但不移除 DXIL (/D__XBOX_STRIP_DXIL=0)
C. 離線且不預先編譯 (/D__XBOX_DISABLE_PRECOMPILE)
在 PC 上您只有選項 C,但在 XBOX 上我們偏好選項 A,因為沒有執行階段負擔。PC 著色器編譯器針對即時 (JIT) 模式執行進行最佳化,因此可以快速編譯 DXIL -> ISA。在 XBOX 上,我們有一個較重量級的編譯器,因為我們預期大部分時間都是離線執行,可以花更長的時間來最佳化程式碼。

外部文件

您可以在 GitHub 上查看完整的原始碼,甚至參與新前端編譯器的開發:DirectXShaderCompiler。 高階著色器語言 (HLSL) 的一般文件可在 Microsoft Docs 上找到:HLSL 參考。 新編譯器與更進階著色器模型的文件現已位於 GitHub 上:DirectXShaderCompiler wiki。

XBOX 上的 DXC 與 Windows 上的 DXC 之間的差異

在 Windows 上,著色器會編譯為 DXIL,然後傳送至 GPU 驅動程式進行最終編譯。在 XBOX 上,由於目標 GPU 硬體是固定的,著色器預設會預先編譯,這讓我們可以在執行階段略過編譯階段。
若要在 XBOX 上編譯著色器,必須指定根簽章,讓編譯器能夠預先編譯著色器。如果著色器在執行階段與另一個根簽章搭配使用,就會發生執行階段編譯,這通常是不理想的。請注意,對於測試著色器或工具,您可以使用 __XBOX_DISABLE_PRECOMPILE 定義完全略過預先編譯,但不建議在一般執行階段使用。

XBOX 著色器模型功能支援

從著色器模型 6.0 開始,XBOX 對選用的著色器模型功能提供逐項支援。如果未使用任何不受支援的選用功能,您可以在 XBOX 上將著色器編譯為以任何著色器模型為目標。 著色器模型功能的詳細資訊可在 GitHub 上找到。下表詳細說明 XBOX 上的著色器模型功能支援。 [1] 如需支援的內建函式與類型清單,請參閱 XBOX Wave 內建函式。 [2] 對於 XBOX One 系列,我們無法依規格所規定的觸發頂點順序旋轉頂點來存取它們,因此會以硬體提供的順序傳回。這與現有 XBOX 重心座標內建函式的行為相符。 [3] 我們不支援 DXR 1.1 RayQuery 物件。不過,我們支援一種稱為內嵌周遊的 XBOX 特有技術,可用來取代 RayQuery 物件。 [4] 在 XBOX 上會忽略承載存取限定詞。 在 XBOX Series X|S 上,著色器編譯器支援原生 16 位元類型,您可以使用編譯旗標 -enable-16bit-types 並將著色器模型版本設為 6.2 或更高來啟用。在 XBOX Series X|S 上,強烈建議盡可能使用原生 16 位元類型,而非最低精確度類型。在未來的版本中,將不再需要使用 -enable-16bit-types,因為原生 16 位元類型將預設啟用。 [5] 如果嘗試使用可程式化位移,會產生 ISA,但產生的程式碼不正確,且無法如預期運作。 [6] 此功能可透過 XB_Store HLSL 內建函式取得 [7] [WaveOpsIncludeHelperLanes] 屬性可以編譯,但 XBOX 編譯器目前會忽略它。

已知問題

  • 如果您使用自訂配置器 (DxcCreateInstance2),在卸載 dxcompiler .dll 之前,不得釋放自訂配置器。
  • 如果著色器已序列化,且 .pdb 名稱與雜湊字串不相符,PIX 就無法自動找到 .pdb。未來我們將在 PIX 中新增一個選項,可在 PIX .pdb 搜尋路徑中的所有 .pdb 中搜尋相符的雜湊,而不論 .pdb 名稱為何。
  • DXIL 大小平均比 DXBC 大小更大。我們正在積極處理 DXIL 大小問題。
  • 反映資料的大小將在未來的版本中大幅縮減。
  • 使用 DXC 建立之著色器的 PIX HLSL 偵錯工具有許多問題。我們正在積極改善品質。
  • __XBOX_ENABLE_SIGNATURE_PACKING 目前僅適用於頂點著色器與像素著色器階段。
  • 我們正在積極改善編譯時間效能與執行階段效能。如果您有特定著色器的編譯時間過長,或未符合您對執行階段效能的預期,請透過 AskHLSL@microsoft.com 寄送電子郵件給我們,或在 XBOX 論壇上與我們聯絡。

了解 GPU 編譯器階段與術語

GPU 編譯器由「前端」與「後端」組成:前端會將 HLSL 剖析為中繼語言,再由「後端」編譯器使用,後端編譯器會進行低階、機器特定的最佳化,並產生 GPU 機器碼。
我們舊的前端編譯器 (稱為 D3DCompiler 或 FXC) 與舊的中繼語言 (DXBC) 都已被以開放 Clang 與 LLVM 標準為基礎的新前端編譯器 (DXCompiler 或 DXC) 與新中繼語言 (DXIL) 取代。此外,在 XBOX 上,Microsoft 已從 “SC” 後端程式碼基底轉移至同樣以 LLVM 為基礎、名為 “NB” 的更新程式碼基底。隨著 GPU 程式碼的複雜度增加,我們需要轉移至更進階且更具彈性的技術。 新的編譯器流程:

XBOX 編譯器上的 NGG 實作 (僅限 Scarlett)

NGG (Next Generation Geometry) 會略過 IA 硬體階段,可大幅提高基本圖形輸送量。 控制 NGG 程式碼產生的其他旗標: 若要利用自動剔除,遊戲必須
  1. 從 VS 匯出寫入所有四個元件的 SV_Position 值。
  2. 將 D3D12_GRAPHICS_PIPELINE_STATE_DESC 中的 D3D12_RASTERIZER_DESC.CullMode 設為 D3D12_CULL_MODE_NONE 以外的值。
D3D12_RASTERIZER_DESC.FrontCounterClockwise 的值會在執行階段讀取,以判斷頂點環繞順序。目前會執行下列類型的剔除:
  1. 背面剔除
  2. 零面積三角形剔除
  3. 檢視範圍剔除
以下是自動剔除函式的 HLSL 實作。

啟用 NGG 的效益

雖然最終目標是預設啟用 NGG 剔除,但目前只有在少數 (一或多個) 已知情況下才有效益。這些情況包括:
  • 硬體的瓶頸在於基本圖形處理 (每個時脈 4 個基本圖形)
  • 繪製具有蛇形網格的高頂點/基本圖形數量 (以產生長串的背面頂點),使得長串的頂點被剔除。
  • 大量只對屬性有貢獻的記憶體存取
  • 大量的屬性匯出
這一切都基於一項假設:被剔除的基本圖形數量足夠多,足以觸及上述任一情境。全螢幕繪製、世界幾何以及引擎中既有的剔除,都會降低此功能的價值。如果工作負載的瓶頸已經在於像素速率,NGG 剔除也不會帶來好處。

未來的改進

這是初始版本,將隨著時間改進。計劃中的改進包括
  1. 調整執行緒群組大小。NGG 剔除需要配置 LDS。較大的執行緒群組大小會因 LDS 配置限制而限制已編譯著色器的佔用率。
  2. 在整個執行緒群組都被剔除時啟用提前結束。
  3. 非內插屬性的每個基本圖形匯出。
  4. 新增啟發學習法,在能以靜態方式判斷無效益時關閉剔除。範例:
    1. 剔除前與剔除後著色器區段中的重複指令 (由於位置與屬性匯出之間的共用)。
    2. Position.Z 為 0——可能不會被剔除的平面 (2D) 三角形。
    3. 小型子群組略過。
    4. 其他次要最佳化。
我們也在考慮新增對使用者定義剔除函式的支援,讓編譯器在為 NGG 編譯時可以呼叫這些函式。 請試用並提供意見反應。

另請參閱

XBOX 主機遊戲開發 (環境與工具)
最後修改於 2026年10月8日