共用方式為


Direct3D 11 (浮點規則)

Direct3D 11 支援數個浮點標記法。 所有浮點數計算運作都在 IEEE 754 32 位元單精確度浮點數規則的定義子集下運作。

32 位元浮點規則

有兩組規則:符合 IEEE-754 的規則,以及偏離標準的規則。

遵循 IEEE-754 規則

有些規則是單一選項,由 IEEE-754 提供選擇。

  • 除以 0 會產生 +/- INF,除了 0/0 得到 NaN 的結果。
  • (+/-) 0 的對數會產生 -INF。 負值 (-0 除外) 的對數會產生 NaN。
  • 負數的反平方根 (rsq) 或平方根 (sqrt) 會產生 NaN。 例外是 -0;sqrt(-0) 會產生 -0,而 rsq(-0) 會產生 -INF。
  • INF - INF = NaN
  • (+/-)INF / (+/-)INF = NaN
  • (+/-) INF * 0 = NaN
  • NaN (任意 OP) 任意值 = NaN
  • 比較 EQ、GT、GE、LT 和 LE,若任一個或兩個運算元皆為 NaN,則傳回 FALSE
  • 比較會忽略 0 的正負號 (因此 +0 等於 -0)。
  • 比較 NE,若任一個或兩個運算元皆為 NaN,則傳回 TRUE
  • 任何非 NaN 值與 +/- INF 比較會傳回正確的結果。

IEEE-754 規則的差異或其他需求

  • IEEE-754 需要浮點運算產生結果,此結果為最接近無限精確結果的可表示值,也稱為 round-to-nearest-even。 Direct3D 11 定義相同的需求:32 位浮點運算會產生在無限精確結果的 0.5 單位最後一個位置內 (ULP) 內的結果。 這表示,例如,允許硬體將結果截斷為 32 位,而不是執行四捨五入到最接近的偶數,因為這會導致最多 0.5 ULP 的錯誤。此規則僅適用于加法、減法和乘法。

  • 不支援浮點例外、狀態位元或設陷。

  • Denorm 會在任何浮點數學運算的輸入和輸出上,排清至保留正負號的零。 例外是針對不操作資料的任何 I/O 或資料移動作業。

  • 包含浮點值的狀態,例如 Viewport MinDepth/MaxDepth、BorderColor 值,可能會提供為 denorm 值,而且可能會在硬體使用之前排清它們。

  • 最小值或最大值作業會針對比較排清 denorm,但結果不一定會是排清 denorm。

  • 運算的 NaN 輸入一律會在輸出產生 NaN。 但 NaN 的精確位元模式不必保持不變 (除非運算操作是原始移動指示 - 不會修改資料)。

  • 只有一個運算元是 NaN 的最小值或最大值運算,會傳回其他運算元做為結果 (與我們前面所說的比較規則相反)。 這是 IEEE 754R 規則。

    浮點最小值和最大值運算的 IEEE-754R 規格指出,如果其中一個最小值或最大值的輸入是 quiet QNaN 值,運算結果就是另一個參數。 例如:

    min(x,QNaN) == min(QNaN,x) == x (same for max)
    

    IEEE-754R 規格的修訂對最小值和最大值採用了不同的行為,當一個輸入為 "signaling" SNaN 值與 QNaN 值比較:

    min(x,SNaN) == min(SNaN,x) == QNaN (same for max)
    
    

    一般而言,Direct3D 遵循算術標準︰IEEE-754 和 IEEE-754R。 但在此案例中有誤差。

    Direct3D 10 及更新版本中的算術規則不會在 quiet 和 signaling NaN 值 (QNaN 與 SNaN 比較) 之間做出區別。 所有 NaN 值都以相同方式處理。 若是最小值和最大值,任何 NaN 的 Direct3D 行為就像是 QNaN 在 IEEE-754R 定義中的處理方式。 (為了完整性,如果兩個輸入都是 NaN,則會傳回任一個 NaN 值)。

  • 另一項 IEEE 754R 規則是 min(-0,+0) == min(+0,-0) == -0 和 max(-0,+0) == max(+0,-0) == +0,其採用正負號,與帶正負號的零的比較規則相反 (如前面所見)。 Direct3D 在此建議 IEEE 754R 行為,但不會強制執行;它允許比較零的結果取決於參數順序,使用忽略正負號的比較。

  • x*1.0f 一律會產生 x (,但反正規化) 除外。

  • x/1.0f 一律產生 x (除了會排清 denorm)。

  • x +/- 0.0f 一律產生 x (除了會排清 denorm)。 但是 -0 + 0 = +0。

  • 合併運算 (例如 mad、dp3) 產生的結果肯定比非合併擴展運算可能最差的序列評估順序精確。 可能最差順序的定義 (基於誤差目的) 對於特定合併運算來說並非固定的定義;它取決於特殊的輸入值。 對於非合併擴展的個別步驟,每一個允許 1 ULP 誤差 (或對於 Direct3D 呼叫的任何指令,若 lax 誤差多於 1 ULP,則允許越大 lax 誤差)。

  • 合併運算遵循與非合併運算相同的 NaN 規則。

  • sqrt 和 rcp 有 1 ULP 誤差。 著色器倒數和倒數平方根指令 rcprsq 各有自己較寬鬆的精確需求。

  • 乘和除各在 32 位元浮點精準度運算 (乘積的精準度為 0.5 ULP,倒數的精準度為 1.0 ULP)。 如果直接實作 x/y,結果必須大於或等於比兩步驟方法的精準度。

64 位元 (雙精確度)浮點規則

硬體和顯示器驅動程式選擇性支援雙精確度浮點。 若要指出支援,當您使用D3D11_FEATURE_DOUBLES呼叫ID3D11Device::CheckFeatureSupport時,驅動程式會將D3D11_FEATURE_DATA_DOUBLESDoublePrecisionFloatShaderOps設定為 TRUE。 驅動程式和硬體必須支援所有雙精確度浮點指令。

雙精確度指令遵循 IEEE 754R 行為需求。

產生去標準化值的支援為雙精確度資料所必要 (不允許 flush-to-zero 行為)。 同樣地,指令不會將去標準化資料讀做帶正負號的零,它們會採用 denorm 值。

16 位元浮點規則

Direct3D 11 也支援浮點數的 16 位標記法。

格式:

  • 在 MSB 位元位置 1 帶正負號位元 (s)
  • 5 位元偏置指数 (e)
  • 10 位元分數 (f),含一個額外的隱藏位元

float16 值 (v) 遵循下列規則:

  • 若 e == 31 且 f != 0,則 v 為 NaN,不考慮 s
  • 如果 e == 31 和 f == 0,則 v = (-1) s*infinity (帶正負號的無限大)
  • 如果 e 介於 0 到 31 之間,則 v = (-1) s*2 (e-15) * (1.f)
  • 如果 e == 0 和 f != 0,則 v = (-1) s*2 (e-14) * (0.f) (反正規化數位)
  • 如果 e == 0 和 f == 0,則 v = (-1) s*0 (帶正負號零)

32 位元浮點規則也會針對 16 位元浮點數保留,並針對前面所述的位元配置調整。 例外狀況包括:

  • 精確度︰16 位元浮點數的未合併運算產生的結果為最接近無限精確結果的可表示值 (進位置最接近偶數,依照 IEEE-754,適用於 16 位元值)。 32 位元浮點規則遵循 1 ULP 誤差,16 位元浮點規則針對非合併運算遵循 0.5 ULP,合併運算則為 0.6 ULP。
  • 16 位元浮點數保留 denorm。

11 位元與 10 位元浮點規則

Direct3D 11 也支援 11 位和 10 位浮點格式。

格式:

  • 不帶正負號的位元
  • 5 位元偏置指数 (e)
  • 11 位元格式為 6 位元分數 (f),10 位元格式為 5 位元分數 (f),兩者皆有一個額外的隱藏位元。

float11/float10 值 (v) 遵循下列規則:

  • 若 e == 31 且 f != 0,則 v 為 NaN
  • 若 e == 31 且 f == 0,則 v = +infinity
  • 如果 e 介於 0 到 31 之間,則 v = 2 (e-15) * (1.f)
  • 如果 e == 0 和 f != 0,則 v = *2 (e-14) * (0.f) (反正規化數位)
  • 若 e == 0 且 f == 0,則 v = 0 (零)

32 位元浮點規則也會針對 11 位元和 10 位元浮點數保留,並針對前面所述的位元配置調整。 例外狀況包括:

  • 精確度︰32 位元浮點規則遵循 0.5 ULP。
  • 10/11 位元浮點數保留 denorm。
  • 任何結果為小於零的運算都會限制為零。

資源

紋理