Skip to main content
名為 Streaming 的範例專案示範了如何使用 Sampler Feedback API 進行紋理串流。它使用 Direct3D 12 標準與延伸 API 來建立 MinMip 回饋對應資源和無序存取檢視,以及 MinMip 對應資源、著色器資源檢視和取樣器。 此範例包含兩個適用於不同平台的組建:適用於 XBOX Series X|S 的 Microsoft Game Development Kit (GDK) 組建,以及桌面 Windows 組建。只有 XBOX Series X|S 組建使用新的 Sampler Feedback Direct3D 12 API。其他平台則使用現有的 Direct3D 12 功能來模擬 Sampler Feedback。此範例的未來版本將支援 Windows 2020 年春季版本中提供的新 Sampler Feedback API。 此外也提供內容產生工具,必須在桌上型電腦上建置並執行,以產生範例中使用的並排紋理資料檔案。 在初始版本中,內容產生工具 (ContentTool) 必須在配備 Direct3D 功能層級 12_0 GPU 的桌上型電腦上執行。在未來版本中,此需求將放寬為功能層級 11_0。Streaming 範例的桌面組建需要支援並排資源第 2 層的功能層級 11_0 GPU。

建置 Streaming 範例與內容工具

若要建置範例,請確定您擁有已更新的 Visual Studio 2017 開發環境、已安裝 1911 GDK,並已安裝 17134 或更新版本的 Windows SDK。開啟解決方案時,如果尚未安裝所有必要的 Visual Studio 功能,系統將自動要求安裝。開啟解決方案 (Streaming\Streaming.sln) 並重建解決方案。發行和分析組建比偵錯組建快得多,但偵錯組建可透過偵錯層進行 Direct3D 12 API 驗證。

建立並部署紋理內容

建置 ContentTool 的發行組建。使用下列命令列執行它: contenttool.exe 64 8192 c:\temp “c:\temp” 參數可替換為任何其他合適的暫存目錄位置。這些選項將產生 64 組 8192 × 8192 具 mipmap 的並排紋理 (漫反射-法線-鏡面反射),總計約 10 GB 的內容。ContentTool 在建立紋理期間會耗用大量記憶體。建議在至少具有 16 GB 記憶體的系統上執行。 將 ContentTool 產生的紋理內容 (.trimg 和 .trdata 檔案) 複製到 Streaming 範例配置中的 “streamingtextures” 子目錄,然後進行部署。 對於 Streaming 開發測試的通用 Windows 平台 (UWP) 組建,紋理檔案必須部署到套件的暫存目錄位置。部署不含內容的 Streaming 應用程式 UWP 組建,並執行一次。範例啟動後會顯示紋理內容遺失的訊息,並開啟檔案總管視窗至應用程式暫存目錄中的某個位置。將紋理資料檔案複製到該暫存目錄的 “streamingtextures” 子目錄。 成功部署內容後,範例啟動時應會顯示彩色立方體網格,如下圖所示。 Streaming 範例 UWP 組建的螢幕擷取畫面,顯示 ContentTool 所產生的紋理內容

控制項與使用方式

此範例是針對 XBOX 控制器所設計。對於範例的桌面組建,建議您將 XBOX 控制器連接到開發電腦。如果無法這樣做,也可以使用下表詳述的鍵盤和滑鼠控制項。

偵錯選項與檢視

  1. 可使用第一個功能表選項循環切換轉譯模式。場景著色器複雜度可從一層 (漫反射-法線-鏡面反射) 提高到三層 (各三組漫反射-法線-鏡面反射)。此外,也可以將 MinMip 對應重疊在場景幾何上。
  2. 串流統計資料預設為啟用,可在 Streaming Debug Views 功能表中切換。串流統計資料包括處理中圖格數量的即時計數器、所有紋理的總虛擬大小、圖格集區的容量和佔用率、延遲統計資料、瓶頸,以及每個 mip 的常駐/曾存取統計資料。
  3. 可以檢查個別串流紋理,包括主要 (並排資源) 紋理及其相關聯的 MinMip 和 MinMip 回饋對應。只要在 Streaming Debug Views 功能表中啟用 Debug Texture Mode,然後使用相機控制項將瞄準十字線對準場景物件即可。系統會顯示其紋理,並可在第一層的漫反射、法線或鏡面反射對應之間選擇。
  4. 可在 Streaming Debug Views 功能表中啟用各種串流子系統的 CPU 計時。

串流引擎概觀

Streaming 範例中的紋理串流引擎是針對串流個別 64 KB 圖格而設計。圖格儲存在記憶體中的單一圖格集區 (一個 ID3D12Heap 物件),預設大小為 512 MB。紋理串流引擎中可以具現化任意數量的並排紋理,唯一的限制是追蹤並排紋理資源及其相關聯 MinMip 和 MinMip 回饋對應之著色器資源檢視與無序存取檢視的描述元堆積最大大小。 下圖代表紋理串流引擎中個別並排紋理的作業週期。 依 GPU 和 CPU 工作分組的流程圖,代表紋理串流引擎中針對個別並排紋理執行的作業週期 作業週期會在每個畫面格重複。但對於任何個別圖格,完成週期需要超過一個畫面格。另請注意,除了從硬碟載入圖格資料的非同步檔案 IO 之外,串流引擎的實作主要是單一執行緒。此方法可將系統的可讀性和彈性最大化。更積極的執行緒處理和最佳化可大幅降低延遲,但會讓程式碼更難理解。

並排紋理建立與場景圖設定

在串流引擎中建立並排紋理時,會建立下列三個資源。
  1. 並排紋理本身,透過 ID3D12Device::CreateReservedResource API 建立。
  2. 小型 MinMip 對應,使用並排紋理的維度除以該格式中單一 64 KB 圖格的維度來建立。例如,BC1 格式的 8192 × 8192 並排紋理會產生 16 × 32 紋素的 MinMip 對應,因為 BC1 中的 64 KB 圖格維度為 512 × 256。
  3. 小型 MinMip 回饋對應,維度與 MinMip 對應相同。
系統會為並排紋理和 MinMip 對應建立著色器資源檢視 (SRV) 描述元,並使用 ID3D12Device8::CreateSamplerFeedbackUnorderedAccessViewX API 為 MinMip 回饋對應建立無序存取檢視 (UAV) 描述元。 為了提高效率,MinMip 回饋對應不會建立為個別資源。而是建立為較大的 Texture2DArray 不透明資源的子配置配量,該資源是透過 ID3D12Device8::CreatePlacedResource1 API 建立。之所以能採用此策略,是因為許多 MinMip 回饋對應共用相同的維度。將它們建立為較大的紋理陣列,可確保硬體擁有最有效率的記憶體封裝配置,此外也確保 MinMip 回饋對應在記憶體中是連續的,從而能非常有效率地進行大量清除和轉碼。 場景圖保存 GPU 可見的描述元,並以每個物件的順序排列。當場景物件連同其相關聯的材質 (並排紋理的選取組合) 一起具現化時,描述元會從串流引擎的描述元堆積複製到場景圖的 GPU 可見描述元堆積。 在建立並排紋理時,會從硬碟載入封裝 mip 尾端 (所有小於 64 KB 圖格大小的 mip 層級),並對應到並排紋理中,而 MinMip 對應則會以第一個封裝 mip 層級的值清除。

場景轉譯與取樣器回饋

轉譯場景之前,系統中的所有回饋對應都會大量清除為回饋對應中可能的最大值:二進位值 0xFF,或 5.3 不帶正負號定點編碼中的 31.875。 在場景轉譯期間,會取樣 MinMip 對應以產生細節層級 (LOD) 限制值,然後套用該限制值來取樣並排紋理。另外,會針對並排紋理收集取樣器回饋,並寫入 MinMip 回饋對應,而不套用 LOD 限制。取樣器回饋是透過高階著色器語言 (HLSL) 函式 FeedbackTexture2D::WriteSamplerFeedback 執行。 取樣器回饋資料具有高度冗餘性。對於相當接近相機的物件,任何特定 64 KB 圖格的螢幕涵蓋範圍保證會相當大。因此,場景著色器預設只執行 1/128 (0.7%) 的取樣器回饋作業。

取樣器回饋資料回讀與分析

CPU 在每個畫面格回讀取樣器回饋資料,以決定接下來需要載入哪些圖格。首先,使用計算著色器將取樣器回饋資料從 GPU 可寫入的回饋陣列紋理資源大量複製到 CPU 可讀取的放置足跡中。接著,CPU 程式碼會逐一查看 MinMip 回饋對應的每個紋素。對於每個紋素,會將 MinMip 回饋值與圖格資料庫比較,以判斷該紋理在該 mip 層級中該位置所需的圖格是否存在。如果圖格不存在,會為該圖格建立圖格追蹤項目,並加入 “Seen Tiles” 佇列。如果圖格已存在,則會標記目前的時間戳記。 處理 MinMip 回饋對應之後,“Seen Tiles” 清單會依 LOD 層級排序,並從最大的 LOD 層級開始,將部分圖格排入佇列以從硬碟載入。載入圖格之前,必須先配置壓縮圖格資料的暫存儲存空間,以及圖格集區中的目的地位置。暫存儲存空間和圖格集區儲存空間的可用性,是決定一次可載入多少圖格的主要限制因素。 圖格排入載入佇列後,會啟動非同步 Win32 檔案 IO 作業以載入圖格。在數個畫面格後完成時,資料會解壓縮至解壓縮暫存位置。在檔案載入和解壓縮的同時,圖格也會排入佇列,以透過 ID3D12CommandQueue::UpdateTileMappings API 對應到 GPU 上的並排資源。任何特定圖格的載入和對應都可能需要數個畫面格才能完成。

圖格完成與淘汰至 MinMip 對應更新

在每個畫面格中,串流引擎會監視各種佇列,以了解圖格載入和解壓縮的完成情況,以及圖格對應的完成情況。已完成載入、解壓縮和對應的圖格會放入 “Complete Tiles” 清單中,現在已準備好透過更新 MinMip 對應來公開給場景轉譯。這些更新會排入佇列,並在每個 MinMip 對應的 CPU 暫存複本中執行,然後使用 ID3D12GraphicsCommandList::CopyTextureRegion 透過紋理複製傳輸到 GPU 可讀取的 MinMip 對應。 “Complete Tiles” 清單也會在每個畫面格依時間戳記排序。任何時間戳記早於特定閾值 (兩秒) 的圖格都會被視為已淘汰,並標記為取消對應和刪除。取消對應的圖格也會導致 MinMip 對應的更新,這些更新會與新載入圖格的 MinMip 對應更新一起排入佇列並處理。

尚未實作的功能與最佳化

此範例僅說明使用 Sampler Feedback 進行紋理串流的一種特定方法。在 CPU 與 GPU 運算、運算與記憶體使用量,以及精確度與感知視覺結果之間做出不同的取捨,將會產生不同的實作。下列附註討論了其中一些取捨。

使用 GPU 計算進行回饋分析

目前的實作使用 CPU 回讀回饋資料,並針對雜湊表中目前已知圖格的資料庫進行分析,以計算要串流載入和淘汰的圖格清單。這項工作也可以在 GPU 上完成,方法是建置 GPU 友善的已知圖格資料結構。計算著色器會在每個畫面格執行,將回饋資料與目前已載入的圖格集合進行差異比較。計算著色器會在每個畫面格產生要載入和卸載的圖格清單。相較於每個畫面格查看整組回饋資料,CPU 接著只需要處理大幅縮減的資料集。

回饋對應解析度

回饋對應維度可選擇為並排紋理大小的任何 2 的乘冪分數 (依 U、V、W 維度個別選擇)。目前,範例使用 64 KB 圖格的維度,但這需要回饋對應分析工作隨著所有資源中可對應的圖格總數而擴展,而圖格總數可能很快就達到數十萬個。選擇回饋對應維度來代表 mip 0 中的 2 × 2 個 64 KB 圖格,可將分析工作減少 75%,而且可能不會大幅影響視覺結果。

在數個並排紋理之間共用回饋對應

場景轉譯著色器使用三個對應到相同 UV 座標的紋理:漫反射、法線和鏡面反射。針對其中一個紋理 (也就是只有漫反射對應) 擷取的取樣器回饋,可以輕鬆地外推,以對集合中的其他紋理做出相同的串流決策,即使那些其他紋理具有不同的圖格大小或紋理維度也一樣。在此案例中,進行此變更可將回饋對應分析工作減少 66%。此外,可以將紋理集合中的圖格封裝在一起,以最佳化硬碟 IO 作業,如此一來,同時從漫反射、法線和鏡面反射各載入一個圖格,就能在單一 IO 要求中完成。範例的未來更新將包含此最佳化。

另請參閱

Sampler Feedback 概觀 (預覽)
Last modified on October 6, 2026