根簽章 1.1 版
根簽章 1.1 版的目的是讓應用程式在描述元堆積中的描述項不會變更,或資料描述項指向的不會變更時,向驅動程式指出驅動程式。 這可讓驅動程式選擇進行優化,可能知道描述元或指向的記憶體在一段時間內是靜態的。
概觀
根簽章版本 1.0 可讓應用程式隨時在 GPU 上正式發行前小眾測試的應用程式隨時,允許描述元堆積的內容及其所指向的記憶體自由變更。 不過,應用程式通常不需要在參考描述項或記憶體的命令之後變更描述元或記憶體的彈性。
應用程式通常能夠:
- 設定描述項 (,並可能指向) 的記憶體,再系結命令清單或套件組合上的描述項資料表或根描述項。
- 請確定這些描述項不會變更,直到參考這些描述項的命令清單 /bundles 上次完成執行為止。
- 請確定描述項指向的資料不會在相同的完整期間內變更。
或者,應用程式可能只能夠接受該資料在較短時間內變更。 在命令清單執行期間,根參數系結 (描述中繼資料表或根描述元) 目前指向資料的命令清單執行期間,特定資料可能是靜態的。 換句話說,應用程式可能會想要在 GPU 時間軸上執行執行,以在透過根參數設定資料的時間週期之間更新一些資料,知道何時將它設定為靜態。
如果描述項或資料描述項指向 ,將不會變更,則特定的優化驅動程式可能是硬體廠商特定的,而且重要的是,它們不會變更可能改善效能以外的行為。 盡可能保留對應用程式意圖的深入瞭解,並不會對應用程式造成負擔。
其中一個優化是,如果許多驅動程式知道應用程式可以對描述元和資料造成靜態性的承諾,許多驅動程式都可以透過著色器產生更有效率的記憶體存取。 例如,如果特定硬體不區分根引數大小,驅動程式可以移除存取堆積中描述元的間接層級,方法是將它轉換成根描述元。
使用 1.1 版開發人員的額外工作是盡可能保證資料的變動性和靜態性,讓驅動程式能夠做出有意義的優化。 開發人員不需要對靜態性做出任何承諾。
根簽章 1.0 版會繼續維持不變,不過重新編譯根簽章的應用程式現在會預設為根簽章 1.1 (,並視需要強製版本 1.0) 。
靜態和變動性旗標
下列旗標是根簽章的一部分,可讓驅動程式在設定時選擇最佳處理個別根引數的策略,並在原始編譯時將相同的假設內嵌至管線狀態物件 (PSO) ,因為根簽章是 PSO 的一部分。
應用程式會設定下列旗標,並套用至描述項或資料。
typedef enum D3D12_DESCRIPTOR_RANGE_FLAGS
{
D3D12_DESCRIPTOR_RANGE_FLAG_NONE = 0,
D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE = 0x1,
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2,
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8
} D3D12_DESCRIPTOR_RANGE_FLAGS;
typedef enum D3D12_ROOT_DESCRIPTOR_FLAGS
{
D3D12_ROOT_DESCRIPTOR_FLAG_NONE = 0,
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE = 0x2,
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC = 0x8
} D3D12_ROOT_DESCRIPTOR_FLAGS;
DESCRIPTORS_VOLATILE
設定此旗標之後,除了系結描述項資料表的命令清單/套件組合已提交且尚未完成執行之外,應用程式隨時都可以變更根描述中繼資料表所指向之描述元堆積中的描述項。 例如,錄製命令清單,並在描述元堆積中變更描述項後,在提交命令清單以供執行 之前 ,所參考的描述項是有效的。 這是根簽章 1.0 版唯一支援的行為。
如果未 設定DESCRIPTORS_VOLATILE 旗標,則描述項是靜態的。 此模式沒有旗標。 靜態描述項表示描述元堆積中描述元堆積中由根描述中繼資料表所指向的描述項,在記錄) 期間,描述項資料表在命令清單/套件組合上設定時已初始化,而且在命令清單/套件 (組合上執行最後一次之後,才能變更描述項。 針對根簽章 1.1 版,靜態描述項是預設假設,而且應用程式必須視需要指定DESCRIPTORS_VOLATILE旗標。
對於搭配靜態描述元使用描述項資料表的套件組合,描述項必須在套組記錄 (時開始準備,而不是呼叫套件組合時) ,而且直到套件組合上次執行完成為止才會變更。 指向靜態描述元的描述項資料表必須在套件組合錄製期間設定,且不會繼承至套件組合。 命令清單可以使用描述項資料表搭配已設定于套件組合中的靜態描述元,並傳回至命令清單。
當描述項是靜態時,有另一個行為變更需要設定DESCRIPTORS_VOLATILE旗標。 與 Texture1D/2D/3D/Cube 檢視 (無關的緩衝區檢視存取權超出範圍,) 無效並產生未定義的結果,包括可能的裝置重設,而不是傳回讀取或卸載寫入的預設值。 若要移除應用程式依賴硬體超出界限存取檢查的能力,是允許驅動程式選擇在認為更有效率的情況下,將靜態描述項存取升階至根描述項存取。 根描述項不支援任何界限外檢查。
如果應用程式在存取描述項時依賴安全超出界限的記憶體存取行為,則必須將存取這些描述項的描述項範圍標示為DESCRIPTORS_VOLATILE。
DATA_VOLATILE
設定此旗標之後,除了系結描述項資料表的命令清單/配套已提交且尚未完成執行之外,CPU 隨時都可以變更描述項所指向的資料。 這是根簽章 1.0 版唯一支援的行為。
旗標可在描述項範圍旗標和根描述元旗標中使用。
DATA_STATIC_WHILE_SET_AT_EXECUTE
設定此旗標之後,描述項所指向的資料無法從基礎根描述元或描述中繼資料表在 GPU 時程表執行期間于命令清單/配套上設定時開始變更,並在後續繪製/分派不會再參考資料時結束。
在 GPU 上設定根描述元或描述中繼資料表之前,即使相同的命令清單/套件組合 也可以 變更此資料。 只要參考資料已完成,根描述元或描述中繼資料表指向該資料仍會在命令清單/套件組合上設定,也可以變更資料。 不過,這麼做需要在下次取值根描述元或描述中繼資料表之前,再次將描述中繼資料表重新系結至命令清單。 這可讓驅動程式知道根描述元或描述中繼資料表所指向的資料已變更。
DATA_STATIC_WHILE_SET_AT_EXECUTE與DATA_VOLATILE之間的基本差異在於DATA_VOLATILE驅動程式無法判斷命令清單中的資料複本是否已變更描述項所指向的資料,而不需執行額外的狀態追蹤。 因此,例如,如果驅動程式可以將任何類型的資料預先擷取命令插入其命令清單中, (讓著色器存取已知資料更有效率,例如) ,DATA_STATIC_WHILE_SET_AT_EXECUTE讓驅動程式知道它只需要在 透過 SetGraphicsRootDescriptorTable設定資料時執行預先擷取資料。 SetComputeRootDescriptorTable 或其中一個方法來設定常數緩衝區檢視、著色器資源檢視或未排序的存取檢視。
對於套件組合,在執行時設定資料的承諾會唯一套用至套件組合的每個執行。
旗標可在描述項範圍旗標和根描述元旗標中使用。
DATA_STATIC
如果設定此旗標,描述項所指向的資料已經由參考記憶體的根描述項或描述項資料表在錄製期間設定在命令清單/套件組合的時間初始化,而且資料必須等到命令清單/套件組合最後一次完成執行之後,才能變更資料。
對於套件組合,靜態持續時間會從根描述項或描述項資料表設定開始,而不是在配套的錄製期間開始,而不是錄製呼叫命令清單。 此外,指向靜態資料的描述項資料表必須在套件組合中設定,且不會繼承。 命令清單可以使用描述項資料表,指向已在套件組合中設定並傳回至命令清單的靜態資料。
旗標可在描述項範圍旗標和根描述元旗標中使用。
結合旗標
一次最多可以指定其中一個 DATA 旗標,但 Sampler 描述元範圍完全不支援 DATA 旗標,因為取樣器不會指向資料。
SRV 和 CBV 描述項範圍沒有任何 DATA 旗標表示假設有預設的DATA_STATIC_WHILE_SET_AT_EXECUTE行為。 選擇此預設值而非DATA_STATIC的原因是,DATA_STATIC_WHILE_SET_AT_EXECUTE在大部分情況下都較可能成為安全的預設值,同時仍會產生比預設更好的優化機會來DATA_VOLATILE。
UAV 描述項範圍的 DATA 旗標不存在表示假設預設的DATA_VOLATILE行為,假設通常會寫入 UAV。
DESCRIPTORS_VOLATILE 無法 與DATA_STATIC結合,但 可以 與其他 DATA 旗標結合。 DESCRIPTORS_VOLATILE可以與DATA_STATIC_WHILE_SET_AT_EXECUTE結合的原因是,變動性描述元仍需要在命令清單/套件組合執行期間準備好描述項,而DATA_STATIC_WHILE_SET_AT_EXECUTE只是在命令清單/套件組合執行子集內對靜態性做出承諾。
旗標摘要
下表摘要說明可能採用的旗標組合。
有效的D3D12_DESCRIPTOR_RANGE_FLAGS設定 | Description |
---|---|
未設定旗標 | 描述項是靜態 (預設) 。 資料的預設假設:適用于 SRV/CBV:DATA_STATIC_WHILE_SET_AT_EXECUTE,以及 UAV 的預設假設:DATA_VOLATILE。 SRV/CBV 的這些預設值可安全地符合大部分根簽章的使用模式。 |
DATA_STATIC | 描述項和資料都是靜態的。 這會最大化驅動程式優化的可能性。 |
DATA_VOLATILE | 描述項是靜態的,而且資料是變動性的。 |
DATA_STATIC_WHILE_SET_AT_EXECUTE | 描述項是靜態的,而且在執行時設定資料是靜態的。 |
DESCRIPTORS_VOLATILE | 描述項是變動性的,而預設假設是關於資料:適用于 SRV/CBV:DATA_STATIC_WHILE_SET_AT_EXECUTE,以及 UAV:DATA_VOLATILE。 |
DESCRIPTORS_VOLATILE |DATA_VOLATILE | 描述項和資料都是變動性的,相當於根簽章 1.0。 |
DESCRIPTORS_VOLATILE |DATA_STATIC_WHILE_SET_AT_EXECUTE | 描述項是變動性的,但請注意,仍然不允許它們在命令清單執行期間變更。 因此,在執行期間透過根描述中繼資料表設定資料時,結合資料為靜態的其他宣告是有效的,基礎描述元實際上是靜態的,超過資料承諾為靜態。 |
有效的D3D12_ROOT_DESCRIPTOR_FLAGS設定 | Description |
---|---|
未設定旗標 | 資料的預設假設:適用于 SRV/CBV:DATA_STATIC_WHILE_SET_AT_EXECUTE,以及 UAV 的預設假設:DATA_VOLATILE。 SRV/CBV 的這些預設值可安全地符合大部分根簽章的使用模式。 |
DATA_STATIC | 資料是靜態的,是驅動程式優化的最佳可能性。 |
DATA_STATIC_WHILE_SET_AT_EXECUTE | 在執行時設定資料是靜態的。 |
DATA_VOLATILE | 相當於根簽章 1.0。 |
1.1 版 API 摘要
下列 API 呼叫會啟用 1.1 版。
列舉
這些列舉包含索引鍵旗標,可指定描述項和資料變動性。
- D3D_ROOT_SIGNATURE_VERSION :版本識別碼。
- D3D12_DESCRIPTOR_RANGE_FLAGS :判斷描述元或資料是否為變動性或靜態的旗標範圍。
- D3D12_ROOT_DESCRIPTOR_FLAGS :與 D3D12_DESCRIPTOR_RANGE_FLAGS類似的旗標範圍,不同之處在于只有資料旗標適用于根描述元。
結構
從 1.0 版) 更新的結構 (包含變動/靜態旗標的參考。
D3D12_FEATURE_DATA_ROOT_SIGNATURE :將此結構傳遞至 CheckFeatureSupport ,以檢查根簽章 1.1 版支援。
D3D12_VERSIONED_ROOT_SIGNATURE_DESC :可以保存任何版本的根簽章描述,且其設計目的是要與下面所列的序列化/還原序列化函式搭配使用。
這些結構相當於 1.0 版中使用的結構,並新增描述項範圍和根描述元的新旗標欄位:
函式
此處所列的方法會取代原始 的 D3D12SerializeRootSignature 和 D3D12CreateRootSignatureDeserializer 函式,因為它們的設計目的是要在任何版本的根簽章上運作。 序列化表單是傳遞至 CreateRootSignature API 的內容。 如果著色器已在其中撰寫根簽章,則已編譯的著色器將會包含已序列化的根簽章。
- D3D12SerializeVersionedRootSignature :如果應用程式以程式方式產生 D3D12_VERSIONED_ROOT_SIGNATURE 資料結構,它就必須使用此函式建立序列化表單。
- D3D12CreateVersionedRootSignatureDeserializer :產生可透過 GetUnconvertedRootSignatureDesc傳回還原序列化資料結構的介面。
方法
ID3D12VersionedRootSignatureDeserializer介面會建立以還原序列化根簽章資料結構。
- GetRootSignatureDescAtVersion :將根簽章描述結構轉換為要求的版本。
- GetUnconvertedRootSignatureDesc :傳回 D3D12_VERSIONED_ROOT_SIGNATURE_DESC 結構的指標。
協助程式結構
已新增協助程式結構,以協助初始化部分 1.1 版結構。
- CD3DX12_DESCRIPTOR_RANGE1
- CD3DX12_ROOT_PARAMETER1
- CD3DX12_STATIC_SAMPLER1
- CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC
請參閱 D3D12 的協助程式結構和函式。
違反靜態性旗標的結果
上述描述項和資料旗標 (,以及缺少特定旗標所隱含的預設值,) 應用程式對驅動程式定義其行為方式的承諾。 如果應用程式違反承諾,則這是不正確行為:結果未定義,而且在不同驅動程式和硬體上可能會不同。
偵錯層具有驗證應用程式接受其承諾的選項,包括使用根簽章 1.1 版隨附的預設承諾,而不需要設定任何旗標。
版本管理
編譯附加至著色器的根簽章時,較新的 HLSL 編譯器預設會在 1.1 版編譯根簽章,而舊的 HLSL 編譯器僅支援 1.0。 請注意,1.1 根簽章無法在不支援根簽章 1.1 的 OS 上運作。
使用著色器編譯的根簽章版本可以使用 強制為特定版本 /force_rootsig_ver <version>
。 如果編譯器可以保留在強制版本編譯根簽章的行為,則強制版本會成功,例如,在僅供優化用途但不會影響行為的根簽章中卸載不支援的旗標。
如此一來,應用程式就可以在建置應用程式時將 1.1 根簽章編譯為 1.0 和 1.1,並根據 OS 支援層級在執行時間選取適當的版本。 不過,應用程式可以個別編譯根簽章 (最有空間效率,特別是需要多個版本) ,與著色器分開。 即使著色器一開始未使用附加的根簽章進行編譯,也可以使用編譯器選項來保留 /verifyrootsignature
編譯器驗證與著色器之根簽章相容性的優點。 稍後在執行時間,可以使用沒有根簽章的著色器來建立 PSO,同時傳遞所需的根簽章 (OS) 支援的適當版本作為個別參數。
相關主題