資源系結概觀

瞭解 DirectX 12 中資源系結的索引鍵是描述元、描述項資料表、描述元堆積和根簽章的概念。

資源和圖形管線

著色器資源 (例如紋理、常數資料表、影像、緩衝區等) 不會直接系結至著色器管線;而是透過 描述項來參考它們。 描述項是一個小型物件,其中包含一個資源的相關資訊。

描述項會分組在一起,以形成 描述項資料表。 每個描述項資料表都會儲存一種資源類型的相關資訊。 有許多不同類型的資源。 最常見的資源包括:

  • (CBV) 常數緩衝區檢視
  • 未排序的存取檢視 (UAV)
  • (SRV) 著色器資源檢視
  • 取樣器

SRV、UAV 和 CBV 描述元可以合併成相同的描述中繼資料表。

圖形和計算管線可藉由依索引參考描述中繼資料表來存取資源。

描述項資料表會儲存在 描述元堆積中。 描述項堆積在理想情況下會包含描述中繼資料表中的所有描述項 (,) 一或多個要轉譯的畫面格。 所有資源都會儲存在使用者模式堆積中。

另一個概念是 根簽章。 根簽章是由應用程式所定義的系結慣例,由著色器用來找出需要存取的資源。 根簽章可以儲存:

  • 描述元堆積中描述項資料表的索引,其中已預先定義描述中繼資料表的配置。
  • 常數,因此應用程式可以將使用者定義常數系結 (稱為 根常數) 直接系結至著色器,而不需要經過描述元和描述中繼資料表。
  • 直接在根簽章內有非常少量的描述項,例如常數緩衝區檢視 (CBV) 每個繪製的變更,藉此節省應用程式,而不需要將這些描述元放在描述元堆積中。

換句話說,根簽章提供效能優化,適用于每次繪製變更的少量資料。

系結的 Direct3D 12 設計會將它與其他工作分開,例如記憶體管理、物件存留期管理、狀態追蹤和記憶體同步處理 (指的是 系結模型與 Direct3D 11) 的差異 。 Direct3D 12 系結的設計目的是要降低額外負荷,並針對最常進行的 API 呼叫進行優化。 它也可在低階到高階硬體之間調整,並從較舊的 (更線性的 Direct3D 11 管線) 調整為較新的 (更平行) 圖形引擎程式設計方法。

資源類型和檢視

資源類型與 Direct3D 11 相同,也就是:

  • Texture1D 和 Texture1DArray
  • Texture2D 和 Texture2DArray、Texture2DMS、Texture2DMSArray
  • Texture3D
  • (具型別、結構化和原始) 的緩衝區

資源檢視類似,但與 Direct3D 11 稍有不同,已新增頂點和索引緩衝區檢視。

  • 常數緩衝區檢視 (CBV)
  • UAV) (未排序的存取檢視
  • 著色器資源檢視 (SRV)
  • 取樣器
  • 轉譯目標檢視 (RTV)
  • DSV (深度樣板檢視)
  • IBV (索引緩衝區檢視)
  • VBV (頂點緩衝區檢視)
  • SOV) 串流輸出檢視 (

著色器實際上只會看到這些檢視的前四個,請參閱 著色器可見描述元堆積 和非 著色器可見描述元堆積

資源系結控制流程

將焦點放在根簽章、根描述元、根常數、描述中繼資料表和描述元堆積上,應用程式的轉譯邏輯流程應該類似下列內容:

  • 建立一或多個根簽章物件 – 一個用於應用程式所需的每個不同系結組態。
  • 使用將搭配使用的根簽章物件建立著色器和管線狀態。
  • 建立一個 (,或在必要時,針對每個轉譯框架包含所有 SRV、UAV 和 CBV 描述元的) 描述元堆積。
  • 使用描述項 () 初始化描述元堆積,其中可能適用于將跨許多畫面重複使用的描述元集合。
  • 要轉譯的每個畫面:
    • 針對每個命令清單:
      • 將目前的根簽章設定為使用 (,並在轉譯期間視需要變更 ,這很少需要) 。
      • 更新新檢視 (的一些根簽章常數和/或根簽章描述元,例如世界/檢視投影) 。
      • 針對要繪製的每個專案:
        • 視需要為每個物件轉譯定義描述元堆積中的任何新描述項。 針對著色器可見描述元堆積,應用程式必須確定使用轉譯期間可能正在執行之轉譯時尚未參考的描述項堆積空間,例如,在轉譯期間透過描述元堆積以線性方式配置空間。
        • 使用描述元堆積所需區域的指標來更新根簽章。 例如,一個描述項資料表可能會指向某些靜態 (未變更) 先前初始化的描述項,而另一個描述中繼資料表可能指向針對目前轉譯所設定的一些動態描述元。
        • 針對個別專案轉譯,更新某些根簽章的常數和/或根簽章描述項。
        • 只有當需要變更) ,且與目前系結的根簽章相容時,才將專案的管線狀態設定為繪製 (。
        • Draw
      • 重複下一個專案 ()
    • 重複 (下一個命令清單)
    • 嚴格地,當 GPU 已完成不再使用的任何記憶體時,就可以釋放它。 如果未提交使用這些描述項的其他轉譯,則不需要刪除其描述元的參考。 因此,後續轉譯可以指向描述元堆積中的其他區域,或者可以使用有效的描述元覆寫過時描述元,以重複使用描述元堆積空間。
  • 重複下一個畫面格 ()

請注意,其他描述項類型、轉譯目標檢視 (RTV) 、深度樣板檢視 (DSV) 、索引緩衝區檢視 (IBV) 、頂點緩衝區檢視 (VBV) ,以及 SOV) (資料流程輸出檢視,會以不同的方式管理。 驅動程式會處理命令清單錄製期間針對每個繪製系結之描述元集的版本設定, (類似于硬體/驅動程式) 如何建立根簽章系結的版本設定。 這與著色器可見描述元堆積的內容不同,應用程式必須透過堆積手動設定,因為它參考繪製之間的不同描述項。 著色器可見的堆積內容版本設定會保留給應用程式,因為它可讓應用程式執行一些動作,例如重複使用不變更的描述元,或使用大型靜態描述元集,並使用著色器索引編制 (,例如透過材質識別碼) 選取要從描述項堆積使用的描述項,或使用不同描述項組合的技術組合。 硬體無法針對 RTV、DSV、IBV、VBV、SOV) 的其他描述元 (類型處理這種類型的彈性。

子位置

在 Direct3D 12 中,應用程式對記憶體管理具有低階控制。 在舊版的 Direct3D 中,包括 Direct3D 11,每個資源會有一個配置。 在 Direct3D 12 中,應用程式可以使用 API 來配置大型記憶體區塊,而大於任何單一物件所需的區塊。 完成後,應用程式可以建立描述項,以指向該大型記憶體區塊的區段。 決定要在大型區塊內放置 (較社區塊的位置) 的程式稱為 子位置。 讓應用程式能夠執行這項操作,可提升計算和記憶體的使用效率。 例如,資源重新命名已過時。 就此情況來說,應用程式可以使用柵欄來判斷何時使用特定資源,以及何時不藉由在命令清單執行上隔離命令清單,其中命令清單需要使用該特定資源。

釋放資源

在可以釋放任何已系結至管線的記憶體之前,GPU 必須完成。

等候畫面轉譯可能是確定 GPU 已完成的最粗略方式。 在更精細的細微性上,您可以再次使用柵欄—當命令記錄到您想要追蹤完成的命令清單中時,請緊接著插入柵欄。 然後,您可以使用柵欄來執行各種同步處理作業。 您提交新的工作 (命令清單) ,該清單會等到指定的柵欄在 GPU 上傳遞,這表示一切完成之前,或者您可以在柵欄通過時要求引發 CPU 事件, (應用程式可以等候睡眠執行緒) 。 在 Direct3D 11 中,這是 EnqueueSetEvent () 。