版權所有 (c) 2023 Advanced Micro Devices, Inc. 保留所有權利。
特此免費授予任何獲得本軟體和相關文件文件(「軟體」)副本的人不受限制地使用本軟體,包括但不限於使用、複製、修改、合併的權利、發布、分發、再授權和/或銷售軟體的副本,並允許向其提供軟體的人員這樣做,但須滿足以下條件:上述版權聲明和本許可聲明應包含在所有副本中或軟體的大部分。
本軟體以「現況」提供,不提供任何明示或暗示的保證,包括但不限於適銷性、特定用途的適用性和不侵權的保證。 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE軟體.
與本機渲染相比,FSR2 使用時間回饋來重建高解析度影像,同時保持甚至提高影像品質。
FSR2 可以為昂貴的渲染操作(例如硬體光線追蹤)提供「實用效能」。
HLSL
CS_6_2
CS_6_6*
* - CS_6_6 用於某些支援 64 寬波前的硬體。
要使用 FSR2,您應該按照以下步驟操作:
雙擊build
目錄中的GenerateSolutions.bat
。
開啟與您的 API 相符的解決方案,並建立該解決方案。
將 API 庫從bin/ffx_fsr2_api
複製到專案中包含第三方庫的資料夾所在的資料夾中。
複製與您要使用的 FSR2 後端相符的庫,例如: bin/ffx_fsr2_api/ffx_fsr2_api_dx12_x64.lib
for DirectX12。
將以下核心 API 頭檔從 src/ffx-fsr2-api 複製到您的專案: ffx_fsr2.h
、 ffx_types.h
、 ffx_error.h
、 ffx_fsr2_interface.h
、 ffx_util.h
、 shaders/ffx_fsr2_common.h
shaders/ffx_fsr2_resources.h
應注意維護檔案複製目的地的相對目錄結構。
複製您選擇的 API 後端的頭文件,例如對於 DirectX12,您將複製dx12/ffx_fsr2_dx12.h
和dx12/shaders/ffx_fsr2_shaders_dx12.h
。應注意維護檔案複製目的地的相對目錄結構。
將ffx_fsr2.h
頭檔包含在您希望與 FSR2 互動的程式碼庫中。
為您的目標 API 建立後端。例如,對於 DirectX12,您應該呼叫ffxFsr2GetInterfaceDX12
。應分配透過呼叫ffxFsr2GetScratchMemorySizeDX12
傳回的大小的暫存緩衝區,並將指向該緩衝區的指標傳遞給ffxFsr2GetInterfaceDX12
。
透過呼叫ffxFsr2ContextCreate
來建立 FSR2 上下文。參數結構的填寫應與您的應用程式的配置相符。有關更多詳細信息,請參閱 API 參考文件。
您應該在每個訊框呼叫ffxFsr2ContextDispatch
來啟動 FSR2 工作負載。參數結構的填寫應與您的應用程式的配置相符。有關更多詳細信息,請參閱 API 參考文檔,並確保以毫秒為單位提供frameTimeDelta
字段。
當您的應用程式終止時(或您希望因其他原因銷毀上下文),您應該呼叫ffxFsr2ContextDestroy
。呼叫此函數之前 GPU 應處於空閒狀態。
子像素抖動應該應用於應用程式的投影矩陣。這應該在執行應用程式的主渲染時完成。您應該使用ffxFsr2GetJitterOffset
函數來計算精確的抖動偏移。有關更多詳細信息,請參閱相機抖動部分。
為了獲得最佳的升級質量,強烈建議您根據我們的指南填充反應性蒙版以及透明度和成分蒙版。您也可以使用ffxFsr2ContextGenerateReactiveMask
作為起點。
應用程式應按以下順序在其使用者介面中公開縮放模式:品質、平衡、效能和(可選)超性能。
應用程式還應該公開銳化滑桿,以允許最終用戶獲得額外的品質。
為了方便最終用戶,FSR2 API 提供了許多已命名的預設縮放比例。
品質 | 每維縮放因子 |
---|---|
品質 | 1.5倍 |
均衡 | 1.7倍 |
表現 | 2.0倍 |
超高性能 | 3.0倍 |
我們強烈建議應用程式在其使用者介面中採用一致的命名和縮放比例。這是為了確保您的應用程式的使用者的使用者體驗是一致的,這些使用者可能有使用 FSR2 的其他應用程式的經驗。
根據您的目標硬體和操作配置,FSR2 將以不同的效能等級運作。
下表總結了在 DX12 中各種硬體上測得的 FSR2 效能。
目標解析度 | 品質 | RX 7900 XTX | RX 6950XT | RX 6900XT | RX 6800XT | RX 6800 | RX 6700XT | RX 6650XT | RX 5700XT | RX維加56 | RX 590 |
---|---|---|---|---|---|---|---|---|---|---|---|
3840x2160 | 質量 (1.5x) | 0.7毫秒 | 1.1毫秒 | 1.2毫秒 | 1.2毫秒 | 1.4毫秒 | 2.0毫秒 | 2.8毫秒 | 2.4毫秒 | 4.9毫秒 | 5.4毫秒 |
平衡 (1.7x) | 0.6毫秒 | 1.0毫秒 | 1.0毫秒 | 1.1毫秒 | 1.4毫秒 | 1.8毫秒 | 2.6毫秒 | 2.2毫秒 | 4.1毫秒 | 4.9毫秒 | |
性能 (2x) | 0.6毫秒 | 0.9毫秒 | 1.0毫秒 | 1.0毫秒 | 1.3毫秒 | 1.7毫秒 | 2.3毫秒 | 2.0毫秒 | 3.6毫秒 | 4.4毫秒 | |
超性能。 (3x) | 0.5毫秒 | 0.8毫秒 | 0.8毫秒 | 0.9毫秒 | 1.1毫秒 | 1.5毫秒 | 1.8毫秒 | 1.7毫秒 | 2.9毫秒 | 3.7毫秒 | |
2560x1440 | 質量 (1.5x) | 0.3毫秒 | 0.5毫秒 | 0.5毫秒 | 0.5毫秒 | 0.7毫秒 | 0.9毫秒 | 1.2毫秒 | 1.1毫秒 | 1.9毫秒 | 2.3毫秒 |
平衡 (1.7x) | 0.3毫秒 | 0.5毫秒 | 0.5毫秒 | 0.5毫秒 | 0.6毫秒 | 0.8毫秒 | 1.1毫秒 | 1.0毫秒 | 1.7毫秒 | 2.1毫秒 | |
性能 (2x) | 0.3毫秒 | 0.4毫秒 | 0.4毫秒 | 0.4毫秒 | 0.6毫秒 | 0.8毫秒 | 0.9毫秒 | 0.9毫秒 | 1.5毫秒 | 1.9毫秒 | |
超性能。 (3x) | 0.2毫秒 | 0.4毫秒 | 0.4毫秒 | 0.4毫秒 | 0.5毫秒 | 0.7毫秒 | 0.8毫秒 | 0.8毫秒 | 1.2毫秒 | 1.7毫秒 | |
1920x1080 | 質量 (1.5x) | 0.2毫秒 | 0.3毫秒 | 0.3毫秒 | 0.3毫秒 | 0.4毫秒 | 0.5毫秒 | 0.6毫秒 | 0.6毫秒 | 1.0毫秒 | 1.3毫秒 |
平衡 (1.7x) | 0.2毫秒 | 0.3毫秒 | 0.3毫秒 | 0.3毫秒 | 0.4毫秒 | 0.5毫秒 | 0.6毫秒 | 0.6毫秒 | 0.9毫秒 | 1.2毫秒 | |
性能 (2x) | 0.2毫秒 | 0.2毫秒 | 0.2毫秒 | 0.3毫秒 | 0.3毫秒 | 0.5毫秒 | 0.5毫秒 | 0.5毫秒 | 0.8毫秒 | 1.1毫秒 | |
超性能。 (3x) | 0.1毫秒 | 0.2毫秒 | 0.2毫秒 | 0.2毫秒 | 0.3毫秒 | 0.4毫秒 | 0.4毫秒 | 0.4毫秒 | 0.7毫秒 | 0.9毫秒 |
數字四捨五入到最接近的 0.1 毫秒,沒有額外的sharpness
,並且可能會發生變化。
使用 FSR2 需要分配一些額外的 GPU 本地記憶體以供 GPU 使用。使用 FSR2 API 時,會在建立 FSR2 上下文時指派此內存,並透過構成後端介面的一系列回調完成分配。此記憶體用於儲存由 FSR2 演算法計算的中間表面以及在應用程式的許多幀中持久存在的表面。下表包括 FSR2 在各種操作條件下使用的記憶體量。 「工作集」列表示演算法在 GPU 上執行時 FSR2 所使用的記憶體總量;這是 FSR2 運作所需的記憶體量。 「持久記憶體」列指示需要為應用程式的後續訊框保留多少「工作集」列;此記憶體儲存 FSR2 消耗的暫存資料。 「可別名記憶體」欄位指示有多少「工作集」欄位可以被 FSR2 作業邊界之外的應用程式所使用的表面或其他資源別名。
您可以透過覆寫 FSR2 後端介面的資源建立和銷毀部分以及轉送別名標誌來控制 FSR2 中的資源建立。這意味著,為了完美整合 FSR2,根據您的操作條件,需要相當於下表「持久記憶體」列的額外記憶體。
解決 | 品質 | 工作集 (MB) | 持久記憶體 (MB) | 可別名記憶體 (MB) |
---|---|---|---|---|
3840x2160 | 質量 (1.5x) | 448MB | 354MB | 93MB |
平衡 (1.7x) | 407MB | 330MB | 77MB | |
性能 (2x) | 376MB | 312MB | 63MB | |
超高性能 (3x) | 323MB | 281MB | 42MB | |
2560x1440 | 質量 (1.5x) | 207MB | 164MB | 43MB |
平衡 (1.7x) | 189MB | 153MB | 36MB | |
性能 (2x) | 172MB | 143MB | 29MB | |
超高性能 (3x) | 149MB | 130MB | 19MB | |
1920x1080 | 質量 (1.5x) | 115MB | 90MB | 24MB |
平衡 (1.7x) | 105MB | 85MB | 20MB | |
性能 (2x) | 101MB | 83MB | 18MB | |
超高性能 (3x) | 84MB | 72MB | 11MB |
數字為近似值,使用 DX12 中的 RX 6700XT GPU 四捨五入到最接近的 MB,並且可能會變更。
有關如何管理 FSR2 記憶體要求的詳細信息,請參閱本文檔中有關記憶體管理的部分。
FSR2 是一種時間演算法,因此需要存取當前幀和前一幀的資料。下表列出了 FSR2 所需的所有外部輸入。
解析度列指示資料是否應採用「渲染」解析度或「演示」解析度。 「渲染」解析度表示資源應與應用程式執行渲染時的解析度相符。相反,「呈現」表示目標的解析度應與要呈現給使用者的解析度相符。所有資源均來自當前渲染幀,對於 DirectX(R)12 和 Vulkan(R) 應用程序,所有輸入資源應在調用
ffxFsr2ContextDispatch
之前分別轉換為D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE
和VK_ACCESS_SHADER_READ_BIT
。
姓名 | 解決 | 格式 | 類型 | 筆記 |
---|---|---|---|---|
顏色緩衝區 | 使成為 | APPLICATION SPECIFIED | 質地 | 應用程式提供的當前幀的渲染解析度顏色緩衝區。如果顏色緩衝區的內容處於高動態範圍 (HDR) 中,則應在FfxFsr2ContextDescription 結構的flags 欄位中設定FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE 標誌。 |
深度緩衝區 | 使成為 | APPLICATION SPECIFIED (1x FLOAT) | 質地 | 應用程式提供的當前幀的渲染解析度深度緩衝區。數據應作為單一浮點值提供,其精度由應用程式控制。建立FfxFsr2Context 時,深度的配置應透過FfxFsr2ContextDescription 結構的flags 欄位傳達給 FSR2。如果深度緩衝區反轉(即 [1..0] 範圍),則應設定FFX_FSR2_ENABLE_DEPTH_INFINITE FFX_FSR2_ENABLE_DEPTH_INVERTED 。如果應用程式提供D32S8 格式的深度緩衝區,則 FSR2 將忽略緩衝區的範本元件,並建立R32_FLOAT 資源來定址深度緩衝區。在 GCN 和 RDNA 硬體上,深度緩衝區與模板緩衝區分開儲存。 |
運動向量 | 渲染或演示 | APPLICATION SPECIFIED (2x FLOAT) | 質地 | 應用程式提供的目前幀的 2D 運動向量在 [ (<-width, -height> .. <width, height> ] 範圍內。如果您的應用程式渲染具有不同範圍的motionVectorScale 向量,您可以使用FfxFsr2DispatchDescription 結構來調整它們以匹配FSR2 的預期範圍在內部,FSR2 在許多情況下使用16 位元量來表示運動向量,這意味著雖然可以提供更高精度的運動向量,但FSR2 將不會從增加的精度中受益。運動向量緩衝區的分辨率應等於渲染分辨率,除非在創建FfxFsr2Context 時在FfxFsr2ContextDescription 結構的flags 字段中設置了FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS 標誌,在這種情況下,它應等於呈現分辨率。 |
反應性面膜 | 使成為 | R8_UNORM | 質地 | 由於渲染影像的某些區域不會在深度緩衝區中留下足跡或包含運動向量,因此 FSR2 提供了對反應性光罩紋理的支持,該紋理可用於向 FSR2 指示這些區域的位置。很好的例子是粒子或不寫入深度或運動向量的 alpha 混合物件。如果未設定此資源,則 FSR2 的著色變更偵測邏輯將盡力處理這些情況,但為了獲得最佳結果,應設定此資源。有關反應性面膜的更多信息,請參閱反應性面膜部分。 |
曝露 | 1x1 | R32_FLOAT | 質地 | 包含為目前影格計算的曝光值的 1x1 紋理。此資源是可選的,如果在建立FfxFsr2Context 時在FfxFsr2ContextDescription 結構的flags 欄位中設定了FFX_FSR2_ENABLE_AUTO_EXPOSURE 標誌,則可以省略該來源。 |
以渲染解析度提供的所有輸入(運動向量除外)都應使用抖動進行渲染。運動向量不應套用抖動,除非存在FFX_FSR2_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION
標誌。
強烈建議將反向無限深度緩衝區與 FSR2 一起使用。但是,支援替代深度緩衝區配置。應用程式應透過在建立FfxFsr2Context
期間設定適當的標誌來通知 FSR2 API 其深度緩衝區配置。下表包含適當的標誌。
FSR2 標誌 | 筆記 |
---|---|
FFX_FSR2_ENABLE_DEPTH_INVERTED | 指示所提供的輸入深度緩衝區資料被反轉的位元[max..0]。 |
FFX_FSR2_ENABLE_DEPTH_INFINITE | 指示所提供的輸入深度緩衝區資料正在使用無限遠平面的位元。 |
時間演算法(無論是抗鋸齒還是放大)的關鍵部分是提供運動向量。 FSR2 接受 2D 運動向量,這些向量對從目前影格中的像素到前一幀中同一像素的位置的運動進行編碼。 FSR2 期望應用程式在 [ <-width, -height> .. <width, height> ] 範圍內提供運動向量;這與螢幕空間相符。例如,螢幕左上角的像素的值為 <width, height> 的運動向量將表示從右下角開始穿過輸入表面的整個寬度和高度的運動。
如果您的應用程式在另一個空間(例如標準化設備座標空間)中計算運動向量,那麼您可以使用FfxFsr2DispatchDescription
結構的motionVectorScale
欄位來指示 FSR2 調整它們以符合 FSR2 的預期範圍。下面的程式碼範例說明如何將運動向量縮放到螢幕空間。下面的範例 HLSL 和 C++ 程式碼說明如何使用 FSR2 主機 API 縮放 NDC 空間運動向量。
// GPU: Example of application NDC motion vector computation
float2 motionVector = (previousPosition.xy / previousPosition.w) - (currentPosition.xy / currentPosition.w);
// CPU: Matching FSR 2.0 motionVectorScale configuration
dispatchParameters.motionVectorScale.x = ( float )renderWidth;
dispatchParameters.motionVectorScale.y = ( float )renderHeight;
在內部,FSR2 在許多情況下使用 16 位元量來表示運動向量,這意味著雖然可以提供更高精度的運動向量,但 FSR2 目前不會從提高的精度中受益。運動向量緩衝區的分辨率應等於渲染分辨率,除非在創建FfxFsr2Context
時在FfxFsr2ContextDescription
結構的flags
字段中設置了FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS
標誌,在這種情況下,它應等於呈現分辨率。
當更多物件提供其運動向量時,FSR2 將執行更好的品質升級。因此,建議所有不透明、經過 alpha 測試和 alpha 混合的物件都應為所有覆蓋的像素寫入其運動向量。如果應用頂點著色器效果(例如滾動 UV),這些計算也應考慮到運動計算中以獲得最佳結果。對於 alpha 混合對象,強烈建議將每個覆蓋像素的 alpha 值儲存到反應掩模中的對應像素。這將使 FSR2 在放大過程中更好地處理 alpha 混合物件。反應掩模對於 alpha 混合物件尤其重要,因為在這些物件中寫入運動向量可能會被禁止,例如粒子。
在 FSR2 的上下文中,術語「反應性」是指為當前幀渲染的樣本對最終放大影像的產生有多大影響。通常,為當前幀渲染的樣本對 FSR2 計算的結果貢獻相對較小的量;然而,也有例外。為了為快速移動的 alpha 混合物件產生最佳結果,FSR2 需要重新投影和累積階段,以便對此類像素更具反應性。由於沒有好的方法可以從顏色、深度或運動向量確定哪些像素是使用 Alpha 混合渲染的,因此當應用程式明確標記此類區域時,FSR2 的表現最佳。
因此,強烈鼓勵應用程式為 FSR2 提供反應遮罩。反應掩模指導 FSR2 在合成當前像素時應減少對歷史資訊的依賴,並允許當前幀的樣本對最終結果做出更多貢獻。反應性遮罩允許應用程式提供 [0.0..1.0] 中的值,其中 0.0 表示像素完全不反應(並且應使用預設的 FSR2 合成策略),值 1.0 表示像素應完全反應反應性的。這是一個浮點範圍,可以根據不同的情況進行客製化。
雖然反應掩模還有其他應用,但反應掩模的主要應用是產生更好的放大影像(包括 alpha 混合物件)的結果。反應性的一個很好的代理實際上是在將 alpha 混合物件合成到場景中時使用的 alpha 值,因此,應用程式應該將alpha
寫入反應性蒙版。應該注意的是,接近 1 的無功值不太可能產生良好的結果。因此,我們建議將最大無功值限制在 0.9 左右。
如果未向 FSR2 提供反應性遮罩(透過將FfxFsr2DispatchDescription
的reactive
欄位設為NULL
),則將使用內部產生的具有清除反應性值的 1x1 紋理。
為了幫助應用程式產生反應性蒙版以及透明度和合成蒙版,FSR2 提供了可選的幫助程式 API。在底層,API 啟動一個計算著色器,它使用基於亮度的啟發式方法計算每個像素的這些值。
希望執行此操作的應用程式可以呼叫ffxFsr2ContextGenerateReactiveMask
函數,並且應該傳遞兩個版本的顏色緩衝區,一個僅包含不透明幾何體,另一個包含不透明和 alpha 混合物件。
除了反應遮罩之外,FSR2 還允許應用程式表示在放大過程中應考慮的其他專業渲染區域。這種特殊渲染的範例包括光線追蹤反射或動畫紋理的區域。
反應性遮罩調整累積平衡,而透明度和合成蒙版則調整像素歷史保護機制。此掩模還消除了亮度不穩定因素的影響。透明度和合成蒙版中值為 0 的像素不會對該像素的鎖定執行任何其他修改。相反,值 1 表示應該完全刪除對該像素的鎖定。
如果未向 FSR2 提供透明度和合成蒙版(透過將FfxFsr2DispatchDescription
的transparencyAndComposition
欄位設為NULL
),則將使用內部產生的具有清除透明度和合成值的 1x1 紋理。
FSR2.2 包括自動產生反應光罩和透明度和合成光罩的實驗功能。要啟用此功能,需要將FfxFsr2DispatchDescription
的enableAutoReactive
欄位設為“TRUE”,並且需要在“colorOpaqueOnly”中提供後台緩衝區的僅不透明部分的副本。然後,FSR2 將在內部自動產生並使用 Reactive mask 和 Transparency & Composition mask。透過分析具有和不具有透明幾何體的顏色緩衝區的差異,並將其與前一幀進行比較,在計算過程中產生蒙版。根據這些計算的結果,每個像素都會分配到反應掩模以及透明度和合成掩模值。要使用遮罩的自動生成,還需要提供以下 4 個值來縮放和限制遮罩的強度(請注意,提到的預設值是建議的起始值,但應根據標題進行調整):
此功能旨在幫助將 FSR2.2 整合到新引擎或遊戲中。但是,為了獲得最佳質量,我們仍然建議您自己渲染反應性蒙版以及透明度和合成蒙版,因為基於材質生成這些值預計比從最終圖像自動生成它們更可靠。
請注意,此功能仍處於實驗階段,將來可能會發生重大變化。
FSR2 提供兩個值來控制執行放大時所使用的曝光。它們如下:
曝光值應與應用程式在應用程式執行的任何後續色調映射過程中使用的曝光值相符。這意味著 FSR2 的運作將與最終色調映射影像中可能可見的內容一致。
在本文檔中所述的 FSR2 演算法的各個階段,FSR2 將計算自己的曝光值以供內部使用。值得注意的是,在寫入最終輸出之前,FSR2 的所有輸出都會反轉此內部色調映射。這意味著 FSR2 傳回與原始輸入訊號相同域的結果。
選擇不當的曝光值可能會對 FSR2 升級的最終品質產生巨大影響。因此,建議應用程式使用FFX_FSR2_ENABLE_AUTO_EXPOSURE
,除非有特殊原因不這樣做。當在FfxFsr2ContextDescription
結構的flags
欄位中設定FFX_FSR2_ENABLE_AUTO_EXPOSURE
時,將使用下面的 HLSL 程式碼中顯示的曝光計算來計算曝光值,該值與 ISO 100 膠片的曝光響應相符。
float ComputeAutoExposureFromAverageLog ( float averageLogLuminance)
{
const float averageLuminance = exp (averageLogLuminance);
const float S = 100.0f ; // ISO arithmetic speed
const float K = 12.5f ;
const float exposureIso100 = log2 ((averageLuminance * S) / K);
const float q = 0.65f ;
const float luminanceMax = ( 78.0f / (q * S)) * pow ( 2.0f , exposureIso100);
return 1 / luminanceMax;
}
FSR2 的主要目標是透過使用依賴大量輸入的時間放大演算法來提高應用程式渲染效能。因此,它在管道中的放置對於確保最高品質的視覺品質和出色的性能之間的正確平衡至關重要。
對於任何影像放大方法,了解如何相對於放大演算法放置其他影像空間演算法都很重要。在放大之前放置這些其他影像空間效果的優點是它們以較低的解析度運行,這當然會為應用程式帶來效能優勢。然而,它可能不適合某些類別的影像空間技術。例如,許多應用程式可能會在最終影像中引入雜訊或顆粒,也許是為了模擬實體相機。在放大器之前執行此操作可能會導致放大器放大噪聲,從而在生成的放大圖像中產生不想要的偽影。下表將常見的即時影像空間技術分為兩列。 「後處理 A」包含通常在 FSR2 升級之前運行的所有技術,這意味著它們都將以渲染解析度運行。相反,「後處理 B」列包含建議在 FSR2 之後運行的所有技術,這意味著它們將以更大的演示解析度運行。
後處理A | 後處理B |
---|---|
螢幕空間反射 | 膠片顆粒 |
螢幕空間環境光遮擋 | 色差 |
降噪器(陰影、反射) | 小插圖 |
曝光(可選) | 色調映射 |
盛開 | |
景深 | |
運動模糊 |
請注意,此處的建議僅供參考,具體取決於您的應用程式實施的具體特徵。
雖然可以產生適當的中間資源、編譯著色器程式碼、設定綁定並提交調度,但使用提供的 FSR2 主機 API 要容易得多。
要使用 API,您應該連結 FSR2 庫(稍後將詳細介紹哪些庫)並包含ffx_fsr2.h
頭文件,該文件又具有以下頭依賴項:
ffx_assert.h
ffx_error.h
ffx_fsr2_interface.h
ffx_types.h
ffx_util.h
要使用 FSR2 API,您應該連結ffx_fsr2_api_x64.lib
,它將提供以應用程式為導向的 API 的符號。然而,FSR2 的 API 具有模組化後端,這意味著可以透過使用匹配的後端來針對不同的圖形 API 和平台。因此,您應該進一步包含符合您要求的後端程式庫,請參考下表。
目標 | 圖書館名稱 |
---|---|
DirectX(R)12 | ffx_fsr2_dx12_x64.lib |
伏爾甘(R) | ffx_fsr2_vk_x64.lib |
請注意,FSR2 API 的模組化架構允許實作自訂後端。有關更多詳細信息,請參閱模組化後端部分。
要開始使用 API,應用程式應先建立一個FfxFsr2Context
結構。這個結構應該位於某個地方,其生命週期大約與您的後緩衝區的生命週期相符;應用程式堆上的某個位置通常是一個不錯的選擇。透過呼叫ffxFsr2ContextCreate
FfxFsr2Context
結構將填入所需的資料。此外,將從ffxFsr2ContextCreate
到後端進行大量調用,該後端作為FfxFsr2ContextDescription
結構的一部分提供給FfxFsr2Context
。這些呼叫將執行創建 FSR2 所需的中間資源以及設定著色器及其關聯的管道狀態等任務。 FSR2 API 不執行任何動態記憶體分配。
需要升級的應用程式的每個框架,您應該呼叫ffxFsr2ContextDispatch
。此函數接受在應用程式生命週期早期建立的FfxFsr2Context
結構,以及應如何執行升級以及對哪些資料執行升級的精確描述。此描述由填寫FfxFsr2DispatchDescription
結構的應用程式提供。
透過呼叫ffxFsr2ContextDestroy
來銷毀上下文。請注意,在嘗試呼叫ffxFsr2ContextDestroy
之前,GPU 應處於空閒狀態,且該函數不會執行隱式同步以確保 FSR2 正在存取的資源目前不在飛行中。這種選擇的原因是避免 FSR2 為那些在可能希望銷毀FfxFsr2Context
時已經執行了足夠同步的應用程式引入額外的 GPU 刷新,這允許應用程式在以下情況下執行 FSR2 API 的最有效的創建和拆卸:必需的。
還有其他輔助函數作為 FSR2 API 的一部分提供。這些輔助函數執行的任務包括計算子像素抖動偏移,以及基於調度解析度和 FSR2 提供的預設縮放模式計算渲染解析度。
有關 FSR2 API 的更詳盡文檔,您可以參考提供的 API 參考文檔。
FSR2 API 的設計意味著 FSR2 演算法的核心實作不知道它位於哪個渲染 API 上。相反,FSR2 呼叫透過介面提供給它的函數,從而允許 FSR2 使用不同的後端。這種設計還允許整合 FSR2 的應用程式提供自己的後端實現,這意味著 FSR2 目前不支援的平台可能會透過實現一些功能而成為目標。此外,擁有自己的渲染抽象的應用程式還可以實現自己的後端,控制FSR2底層功能的各個方面,包括記憶體管理、資源創建、著色器編譯、著色器資源綁定以及將FSR2工作負載提交到圖形裝置.
在核心 API 和後端之間已經概述的分離之後,FSR2 API 將開箱即用地編譯成多個函式庫。這表示如果您希望使用 FSR2 提供的後端,您應該連結核心 FSR2 API 程式庫以及符合您要求的後端。
FSR2 的公開版本附帶 DirectX(R)12 和 Vulkan(R) 後端,但也可依要求提供其他後端。請與您的 AMD 開發技術代表聯繫以獲取更多資訊。
如果 FSR2 API 與所提供的後端之一(例如:DirectX(R)12 或 Vulkan(R))一起使用,則直接使用主機應用程式提供的圖形裝置將 FSR2 所需的所有資源建立為提交資源。然而,透過覆蓋後端介面中存在的建立和銷毀函數系列,應用程式可以更精確地控制 FSR2 的記憶體管理。
為此,您可以透過傳遞給ffxFsr2ContextCreate
函數的FfxFsr2ContextDescription
結構向 FSR2 提供完整的自訂後端,也可以擷取所需 API 的後端並覆寫資源建立和銷毀函數以自行處理它們。為此,只需覆蓋fpCreateResource
和fpDestroyResource
函數指標。
// Setup DX12 interface.
const size_t scratchBufferSize = ffxFsr2GetScratchMemorySizeDX12();
void * scratchBuffer = malloc(scratchBufferSize);
FfxErrorCode errorCode = ffxFsr2GetInterfaceDX12(&contextDescription.callbacks, m_pDevice-> GetDevice (), scratchBuffer, scratchBufferSize);
FFX_ASSERT (errorCode == FFX_OK);
// Override the resource creation and destruction.
contextDescription.callbacks.createResource = myCreateResource;
contextDescription.callbacks.destroyResource = myDestroyResource;
// Set up the context description.
contextDescription.device = ffxGetDeviceDX12(m_pDevice-> GetDevice ());
contextDescription.maxRenderSize.width = renderWidth;
contextDescription.maxRenderSize.height = renderHeight;
contextDescription.displaySize.width = displayWidth;
contextDescription.displaySize.height = displayHeight;
contextDescription.flags = FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE
| FFX_FSR2_ENABLE_DEPTH_INVERTED
| FFX_FSR2_ENABLE_AUTO_EXPOSURE;
// Create the FSR2 context.
errorCode = ffxFsr2ContextCreate(&context, &contextDescription);
FFX_ASSERT (errorCode == FFX_OK);
對於控制 FSR2 所需的記憶體管理的應用程式來說,一個有趣的優點是可以執行資源別名,這可以節省記憶體。記憶體要求中的表格展示了透過使用此技術可以節省的成本。為了實現此表中所示的節省,應該找到一個適當的記憶體區域(其中的內容不需要在對 FSR2 調度的呼叫中保留),以便與 FSR2 所需的可別名資源共用。 FSR2 的核心 API 透過 FSR2 後端介面進行的每個FfxFsr2CreateResourceFunc
呼叫都將包含一組標誌,作為FfxCreateResourceDescription
結構的一部分。如果在flags
欄位中設定了FFX_RESOURCE_FLAGS_ALIASABLE
,則表示該資源可以安全地與渲染訊框中的其他資源建立別名。
時間抗鋸齒 (TAA) 是一種使用先前幀的輸出從當前幀構建更高品質輸出的技術。由於 FSR2 具有類似的目標 - 儘管還有提高渲染影像解析度的附加目標 - 不再需要在應用程式中包含單獨的 TAA 通道。
FSR2 依賴應用程式在渲染時應用子像素抖動 - 這通常包含在相機的投影矩陣中。為了簡化相機抖動的應用,FSR2 API 提供了一小組實用函數,用於計算一系列單獨抖動偏移中特定幀的子像素抖動偏移。
int32_t ffxFsr2GetJitterPhaseCount ( int32_t renderWidth, int32_t displayWidth);
FfxErrorCode ffxFsr2GetJitterOffset ( float * outX, float * outY, int32_t jitterPhase, int32_t sequenceLength);
在內部,這些函數實現了 Halton[2,3] 序列 [Halton]。 Halton 序列的目標是提供空間上分離的點,覆蓋可用空間。
重要的是要了解從ffxFsr2GetJitterOffset
傳回的值位於單位像素空間中,為了將其正確地合成到投影矩陣中,我們必須將它們轉換為投影偏移。上圖顯示了單位像素空間和投影空間中的單一像素。下面的程式碼清單顯示如何將子像素抖動偏移值正確地合成到投影矩陣中。
const int32_t jitterPhaseCount = ffxFsr2GetJitterPhaseCount(renderWidth, displayWidth);
float jitterX = 0 ;
float jitterY = 0 ;
ffxFsr2GetJitterOffset (&jitterX, &jitterY, index, jitterPhaseCount);
// Calculate the jittered projection matrix.
const float jitterX = 2 . 0f * jitterX / ( float )renderWidth;
const float jitterY = - 2 . 0f * jitterY / ( float )renderHeight;
const Matrix4 jitterTranslationMatrix = translateMatrix(Matrix3::identity, Vector3(jitterX, jitterY, 0 ));
const Matrix4 jitteredProjectionMatrix = jitterTranslationMatrix * projectionMatrix;
抖動應該應用於所有渲染。這包括不透明、Alpha 透明和光線追蹤物件。對於光柵化對象,由ffxFsr2GetJitterOffset
函數計算的子像素抖動值可以應用於相機投影矩陣,該矩陣最終用於在頂點著色期間執行變換。對於光線追蹤渲染,子像素抖動應應用於光線的原點 - 通常是相機的位置。
無論您選擇使用建議的ffxFsr2GetJitterOffset
函數還是您自己的序列產生器,您都必須設定FfxFsr2DispatchDescription
結構的jitterOffset
字段,以通知 FSR2 已應用的抖動偏移量,以便渲染每個幀。此外,如果不使用建議的ffxFsr2GetJitterOffset
函數,應注意抖動序列永遠不會產生空向量;即 X 和 Y 維度上的值均為 0。
下表顯示了每種預設質量模式的抖動序列長度。
品質模式 | 比例因子 | 序列長度 |
---|---|---|
品質 | 1.5x(每個維度) | 18 |
均衡 | 1.7x(每個維度) | 23 |
表現 | 2.0x(每個維度) | 32 |
超高性能 | 3.0x(每個維度) | 72 |
風俗 | [1..n]x(每個維度) | ceil(8 * n^2) |
大多數具有即時渲染的應用程式在任何兩個連續幀之間都具有很大程度的時間一致性。但是,在某些情況下,相機變換的變更可能會導致渲染內容發生突然變化。在這種情況下,FSR2不太可能能夠重複使用先前框架累積的任何數據,並且應該清除此數據以將其排除在合成過程中。為了向FSR2表明相機發生了跳轉切割,您應該將FfxFsr2DispatchDescription
結構的reset
字段設為不連續相機轉換的第一個幀的true
。
使用重置標誌時,渲染效能可能比典型的框架操作略低,因為FSR2將清除一些其他內部資源。
應用負MIPMAP偏壓通常會產生具有更好紋理細節的高尺度影像。我們建議將以下公式應用於您的MIPMAP偏見:
mipBias = log2(renderResolution/displayResolution) - 1.0 ;
建議應用程式調整了特定高頻紋理內容的MIP偏置,該內容容易顯示出時間變性問題。
下表說明了MIPMAP偏移因子,該因素是由評估上述偽代碼的縮放比例與應用程式應暴露於最終用戶所建議的質量模式相匹配的縮放比率的。
品質模式 | 比例因子 | mipmap偏見 |
---|---|---|
品質 | 1.5倍(每個維度) | -1.58 |
均衡 | 1.7倍(每個維度) | -1.76 |
表現 | 2.0倍(每個維度) | -2.0 |
超效能 | 3.0倍(每個維度) | -2.58 |
frameTimeDelta
結構提供了FfxFsr2DispatchDescription
API的FSR2 API。該值以毫秒為單位:如果以60fps運行,則通過的值應約為16.6f 。
此值用於FSR 2自動暴露功能的時間分量中。這允許為品質目的調整歷史記錄累積。
FSR2支援高動態範圍影像。若要啟用此功能,您應該在FfxFsr2ContextDescription
結構的flags
欄位中設定FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE
位元。影像應在線性色彩空間中提供給FSR2。
FSR2的未來修訂版可能會提供對其他色彩空間的支援。
FSR2旨在利用一半的精度(FP16)硬體加速度,以實現最高的性能。但是,為了為應用程式提供最大的相容性和靈活性,FSR2還包括使用完整的精確度(FP32)操作編譯著著色器的能力。
建議在支援它的所有硬體上使用FP16版本的FSR2。您可以透過查詢Directx(R)12中的D3D12_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT
(R)12-您應該檢查D3D[11/12]_SHADER_MIN_PRECISION_16_BIT
和圖形,BEFD_MIN_PRECISION_16_BIT和FLAFTBEFS4,BEFFS。對於Vulkan,如果未設定VkPhysicalDeviceFloat16Int8FeaturesKHR::shaderFloat16
,則您應該後備到FP32版本的FSR2。同樣,如果未設定VkPhysicalDevice16BitStorageFeatures::storageBuffer16BitAccess
,則也應該後備到FP32版本的FSR2。
要在FSR2著色器原始碼中啟用FP32路徑,您應該將FFX_HALF
定義為1
。為了在FP16和FP32之間共享演算法的大多數原始程式碼(確保高度的程式碼共享以支援正在進行的維護),您會注意到FSR2 Shader原始程式碼使用一組類型宏,可在著色器來源中的16位和32位基本型。
FidelityFX類型 | FP32 | FP16 |
---|---|---|
FFX_MIN16_F | float | min16float |
FFX_MIN16_F2 | float2 | min16float2 |
FFX_MIN16_F3 | float3 | min16float3 |
FFX_MIN16_F4 | float4 | min16float4 |
上表列舉了抽象FidelityFX SDK類型之間的映射和固有類型之間的映射,這些類型將根據編譯過程中著色器來源的配置來取代。
現代GPU以SIMT方式一起執行線程的集合(稱為Wavefronts)。構成單一波前的螺紋的精確數量是一個特定於硬體的數量。一些硬件,例如AMD的GCN和基於RDNA的GPU支持,將64個線程聚集到一個波前。根據演算法的執行的精確特徵,較優先的波前寬度可能或多或少是有利的。隨著著色器型號6.6的引入,Microsoft添加了通過HLSL特定波前寬度的能力。對於硬件,例如支援32和64個寬波前寬度的RDNA,這是一個非常有用的工具,用於優化目的,因為它提供了一種乾淨可移植的方法,要求驅動器軟體堆疊執行具有特定寬度的波蘭。
對於基於rDNA和基於rDNA的GPU並使用Microsoft Agility SDK運行的DirectX(R)12個應用程序,FSR2主機API將選擇一個64寬的波前寬度。
可以為上下文描述結構提供一個回調函數,以透過FSR 2運行時傳遞文字警告到基礎應用程式。所描述的fpMessage
成員是類型FfxFsr2Message
,它是傳遞各種類型的字串訊息的功能指標。將此變數指派給適當的函數,然後傳遞FfxFsr2ContextDescription
的標誌成員中的FFX_FSR2_ENABLE_DEBUG_CHECKING
FLAG將啟用此功能。建議僅在調試開發建置中啟用這一點。
當檢查員觀察可能的問題時可能發生的輸出類型的範例如下:
FSR2_API_DEBUG_WARNING: FFX_FSR2_ENABLE_DEPTH_INFINITE and FFX_FSR2_ENABLE_DEPTH_INVERTED present, cameraFar value is very low which may result in depth separation artefacting
FSR2_API_DEBUG_WARNING: frameTimeDelta is less than 1.0f - this value should be milliseconds (~16.6f for 60fps)
FSR2演算法在一系列階段實現,如下:
此演算法的每個通過階段都在此之後的各節中列出,但是完整的FSR2演算法的資料流如下圖所示。
計算亮度金字塔階段有兩個責任:
下表包含計算亮度金字塔階段消耗的所有資源。
時間層指示應從哪個框架來源。 「目前框架」意味著應從為接下來要介紹的框架所建立的資源中取得資料。 「先前的幀」表示該資料應來自為剛剛呈現的框架所建立的資源。解析度列指示資料是否應為“渲染”解析度或“表示”解析度。 「渲染」解析度表示資源應與應用程式執行其渲染的解析度相符。相反,「演示」表明目標的分辨率應匹配要向使用者呈現的內容匹配。
姓名 | 時間層 | 解決 | 格式 | 類型 | 筆記 |
---|---|---|---|---|---|
顏色緩衝區 | 當前框架 | 使成為 | APPLICATION SPECIFIED | 質地 | 應用程式提供的當前幀的渲染解析度顏色緩衝區。如果顏色緩衝區的內容在高動態範圍內(HDR),則應在FfxFsr2ContextDescription 結構的FFXFSR2ContextDescription結構的flags 欄位中設定FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE 。 |
下表包含透過計算亮度金字塔階段產生或修改的所有資源。
時間層指示應從哪個框架來源。 「目前框架」意味著應從為接下來要介紹的框架所建立的資源中取得資料。 「先前的幀」表示該資料應來自為剛剛呈現的框架所建立的資源。解析度列指示資料是否應為“渲染”解析度或“表示”解析度。 「渲染」解析度表示資源應與應用程式執行其渲染的解析度相符。相反,「演示」表明目標的分辨率應匹配要向使用者呈現的內容匹配。
姓名 | 時間層 | 解決 | 格式 | 類型 | 筆記 |
---|---|---|---|---|---|
曝露 | 當前框架 | 1x1 | R32_FLOAT | 質地 | 1x1紋理,其中包含針對目前幀計算的曝光值。此資源是可選的,如果FFXFSR2ContextDescription在建立FfxFsr2Context 時, FFX_FSR2_ENABLE_AUTO_EXPOSURE FLAG在FfxFsr2ContextDescription 結構的flags 欄位中設定。 |
目前的亮度 | 當前框架 | Render * 0.5 +麥片鏈 | R16_FLOAT | 質地 | 渲染解析度紋理的50%的紋理,其中包含當前框架的亮度。分配完整的MIP鏈。 |
使用FidelityFX單次降低來實現運算亮度金字塔階段