跳轉到主要內容

簡介

將現有的高階著色器語言 (HLSL) 著色器從 D3DCompiler (FXC) 移植至 DXCompiler (DXC) 時,應以本主題作為參考依據。具體來說,本主題提供下列項目的詳細資訊:
  1. 啟用部分在 DXC 上預設停用的舊 FXC 編譯行為。DXC 透過下列編譯器旗標支援此功能:
    • -Gec:啟用 Direct3D 9 回溯相容性 (例如,啟用僅在 Direct3D 9 以前受支援之 COLOR 語意的支援)。
    • -HV:將語言版本設為 2016 (也就是 -HV 2016) 以啟用 FXC 回溯相容性。這會啟用 FXC 上可用的特定舊版語言語意。
    • -flegacy-macro-expansion:在執行語彙基元貼上作業之前展開運算元 (FXC 行為)。
    • -flegacy-resource-reservation:保留未使用的明確暫存器指派,以便與著色器模型 5.0 及更早版本相容。
    • -D __XBOX_PRECOMPILE_ALL_STAGES:對於 XBOX Series X|S,著色器預先編譯要保守得多。XBOX One 的預設值維持不變。如需詳細資訊,請參閱 XBOX 定義。
  2. 提供有關在 FXC 上受支援但在 DXC 上不再受支援之舊版已淘汰 HLSL 語法的資訊。

編譯器 .dll 介面變更

建議使用新的 IDxcCompiler3::Compile 函式來編譯 DXC 著色器。如需可讓現有程式碼更容易移植至新介面的協助程式常式以及範例程式碼的詳細資訊,請參閱使用 DXC。

與 FXC 行為的回溯相容性

內建函式 pow 的純乘法模式

根據預設,DXC 一律使用 log-mul-exp 模式 (說明如下) 來實作 pow 函式。相反地,FXC 在某些情境中也會改用 純乘法 模式來實作 pow 函式。例如,對於較小的 y 常數值 (例如 pow(x, 3)),FXC 會使用 純乘法 模式。這可能導致 pow 函式在某些情況下,使用 FXC 與 DXC 編譯時產生不同的結果。例如,對於執行階段值 x=0,pow(x,3) 在 DXC 與 FXC 上分別評估為 NaN 與 0。若要在 DXC 上達成與 FXC 相同的 pow 函式行為,請在編譯期間將語言版本設為 2016 (使用旗標 -HV 2016)。

使用 log-mul-exp 模式實作 pow 的範例

使用純乘法模式實作 pow 的範例

超出範圍的陣列存取

根據預設,DXC 在發現對陣列的常數索引參考超出範圍時會發生錯誤。例如,下列 HLSL 著色器會編譯失敗,並出現錯誤訊息:error: array index 3 is out of bounds。只有當超出範圍的存取發生在未使用或無效的程式碼中時,您才能將語言版本設為 2016 (也就是使用 -HV 2016 旗標),將此錯誤轉換為警告。

無法遵循 unroll 屬性時發出警告

當迴圈套用了 unroll 屬性,且無法在編譯時期確定迴圈次數或迴圈次數超過特定閾值時,根據預設,DXC 會無法編譯如下列的著色器。若要將此失敗轉換為警告,請將語言版本設為 2016。在 DXC 上使用 -HV 2016 旗標編譯下列著色器時,它會在不展開迴圈的情況下成功編譯,並產生警告訊息:warning: Could not unroll the loop.

COLOR 語意

DXC 預設不支援 COLOR 語意。撰寫以 DXC 為目標的新 HLSL 著色器時,您應改用 SV_Target。不過,DXC 也提供選項,可透過傳遞 -Gec 旗標來編譯參考 COLOR 語意的著色器。例如,使用 -Gec 旗標時,下列 HLSL 程式碼應可在 DXC 上成功編譯。

常數陣列上的 Length 屬性

在 -Gec 旗標下,DXC 支援常數陣列上的 Length 屬性,如下列範例所示。

寫入全域變數

在 HLSL 中,全域變數被視為常數,但與 FXC 相同,DXC 也可透過 -Gec 旗標支援寫入全域變數,如下列範例所示。

使用 -flegacy-resource-reservation 旗標的舊版資源保留

對於著色器模型 5.0 或更早版本,FXC 在為已使用的資源進行暫存器配置時,會將未使用資源的暫存器配置納入考量。例如,在 FXC 上以 SM5.0 與 5.1 編譯下列著色器時,Tex1[1] 分別繫結至 t4 與 t0。使用 DXC 時,若要以 SM5.0 或更早版本達成 FXC 的資源配置行為,請使用 -flegacy-resource-reservation 旗標。

FXC 搭配 SM5.0 的資源繫結

FXC 搭配 SM5.1 的資源繫結

DXC 搭配 SM6.0 且不使用 -flegacy-resource-reservation 旗標的資源繫結

DXC 搭配 SM6.0 且使用 -flegacy-resource-reservation 旗標的資源繫結

使用 -flegacy-macro-expansion 旗標的舊版巨集展開

下列 HLSL 著色器在 FXC 上可成功編譯,但在 DXC 上會發生錯誤,因為 b##slot 會被替換為 bSLOT_VAL 而非 b3,因而導致編譯失敗。若要在 DXC 上達成 FXC 的語彙基元替換行為,請使用額外的旗標 “-flegacy-macro-expansion” 進行編譯。
在此情況下,您可以遵循標準前置處理器規則來避免使用 -flegacy-macro-expansion 旗標。
對於語彙基元不是巨集引數的情況,-flegacy-macro-expansion 並沒有幫助,但 fxc 仍會展開這些語彙基元。即使使用了 -flegacy-macro-expansion,下列程式碼仍會導致錯誤。
下列變更會讓 HLSL 與標準前置處理器規則相容,不再需要 -flegacy-macro-expansion 選項。

不受支援的 FXC 行為

Effect Framework

與效果架構相關的功能已不再受支援。

進入函式上的 Uniform 參數

進入函式上的 Uniform 參數已不再受支援。

介面

介面已不再受支援。

不再支援維度特定的紋理取樣函式

tex1D、tex2D 與類似取樣函式的支援現已淘汰。若要了解如何移植至受支援的取樣函式,請參閱下列範例。

使用已不再受支援之舊取樣語法的範例

顯示受支援取樣語法的範例

不支援語意重疊

DXC 不允許使用重複的語意。例如,下列著色器將在 DXC 上編譯失敗。

不支援以 “ConstantBuffer” 作為常數緩衝區名稱

從 SM5.1 開始,HLSL 使用 ConstantBuffer 範本建構支援可索引的常數緩衝區。因此,ConstantBuffer 是保留關鍵字,DXC 不允許將其用作緩衝區名稱。

聯絡我們

如果您有疑問、需要協助或想要回報問題,可以透過 AskHLSL@microsoft.com 與我們聯絡。

另請參閱

著色器編譯器
最後修改於 2026年10月8日