Firma radice versione 1.1

Lo scopo di Root Signature versione 1.1 è consentire alle applicazioni di indicare ai driver quando i descrittori in un heap descrittore non cambieranno o i descrittori di dati puntano a non modificheranno. Ciò consente ai driver di eseguire ottimizzazioni che potrebbero essere possibili sapendo che un descrittore o la memoria a cui punta è statico per un certo periodo di tempo.

Panoramica

La versione radice della firma 1.0 consente il contenuto degli heap del descrittore e la memoria a cui puntano per essere liberamente modificati dalle applicazioni ogni volta che gli elenchi di comandi o i bundle che fanno riferimento a essi sono potenzialmente in anteprima sulla GPU. Molto spesso, tuttavia, le applicazioni non necessitano effettivamente della flessibilità necessaria per modificare i descrittori o la memoria dopo la registrazione dei comandi che fanno riferimento a tali descrittori.

Le applicazioni sono spesso facilmente in grado di:

  • Configurare i descrittori (e possibile la memoria a cui puntano) prima di binding di tabelle descrittori o descrittori radice in un elenco di comandi o in un bundle.
  • Assicurarsi che questi descrittori non cambieranno finché l'elenco di comandi /bundle che fa riferimento a tali descrittori non avrà terminato l'esecuzione per l'ultima volta.
  • Assicurarsi che i dati a cui puntano i descrittori non cambino per la stessa durata intera.

In alternativa, un'applicazione può essere in grado di rispettare solo che i dati non cambiano per un periodo di tempo più breve. In particolare, i dati potrebbero essere statici per l'intervallo di tempo durante l'esecuzione dell'elenco di comandi che un'associazione di parametri radice (tabella descrittore o descrittore radice) punta attualmente ai dati. In altre parole, un'applicazione può voler eseguire l'esecuzione sulla sequenza temporale della GPU che aggiorna alcuni dati tra periodi di tempo in cui viene impostata tramite un parametro radice, sapendo che quando è impostato sarà statico.

Se i descrittori o i descrittori di dati puntano a , non cambieranno, i driver di ottimizzazioni specifici potrebbero essere specifici del fornitore dell'hardware e, in particolare, non modificano il comportamento oltre a migliorare le prestazioni. Mantenere il maggior numero possibile di conoscenze sulle finalità dell'applicazione non comporta un carico di lavoro sulle applicazioni.

Un'ottimizzazione consiste nel fatto che molti driver possono produrre accessi di memoria più efficienti da parte degli shader se conoscono le promesse che un'applicazione può fare in merito al livello statico dei descrittori e dei dati. Ad esempio, i driver potrebbero rimuovere un livello di riferimento indiretto per l'accesso a un descrittore in un heap convertendolo in un descrittore radice se l'hardware specifico non è sensibile alle dimensioni dell'argomento radice.

L'attività aggiuntiva per gli sviluppatori che usano la versione 1.1 consiste nel fare promesse sulla volatilità e sul livello statico dei dati laddove possibile, in modo che i driver possano apportare le ottimizzazioni che hanno senso. Gli sviluppatori non devono fare promesse sulla static-ness.

La versione 1.0 della firma radice continua a funzionare invariata, anche se le applicazioni che ricompilano le firme radice verranno impostate per impostazione predefinita su Root Signature 1.1 (con un'opzione per forzare la versione 1.0, se necessario).

Flag statici e volatili

I flag seguenti fanno parte della firma radice per consentire ai driver di scegliere una strategia per gestire al meglio i singoli argomenti radice quando vengono impostati e incorporare gli stessi presupposti in oggetti stato pipeline (PSO) quando vengono originariamente compilati, poiché la firma radice fa parte di un PSO.

I flag seguenti vengono impostati dall'app e si applicano ai descrittori o ai dati.

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

Con questo flag impostato, i descrittori in un heap descrittore a cui punta una tabella del descrittore radice possono essere modificati dall'applicazione in qualsiasi momento, ad eccezione del fatto che l'elenco dei comandi o i bundle che associano la tabella del descrittore sono stati inviati e non sono stati completati l'esecuzione. Ad esempio, la registrazione di un elenco di comandi e la successiva modifica dei descrittori in un heap descrittore a cui fa riferimento prima di inviare l'elenco di comandi per l'esecuzione è valida. Si tratta dell'unico comportamento supportato di Root Signature versione 1.0.

Se il flag DESCRIPTORS_VOLATILE non è impostato, i descrittori sono statici. Non esiste alcun flag per questa modalità. I descrittori statici indicano che i descrittori in un heap descrittore a cui punta una tabella del descrittore radice sono stati inizializzati dal momento in cui la tabella del descrittore è impostata su un elenco di comandi /bundle (durante la registrazione) e i descrittori non possono essere modificati fino a quando l'elenco di comandi o il bundle non è stato completato l'esecuzione per l'ultima volta. Per La firma radice versione 1.1, i descrittori statici sono il presupposto predefinito e l'applicazione deve specificare il flag DESCRIPTORS_VOLATILE quando necessario.

Per i bundle che usano tabelle descrittori con descrittori statici, i descrittori devono essere pronti a partire dal momento in cui il bundle viene registrato (anziché quando viene chiamato il bundle) e non modificare fino al termine dell'esecuzione del bundle per l'ultima volta. Le tabelle del descrittore che puntano ai descrittori statici devono essere impostate durante la registrazione del bundle e non ereditate nel bundle. È valido per un elenco di comandi usare una tabella descrittore con descrittori statici impostati in un bundle e restituiti all'elenco di comandi.

Quando i descrittori sono statici, è presente un'altra modifica nel comportamento che richiede l'impostazione del flag DESCRIPTORS_VOLATILE. Gli accessi out of bounds a any Buffer views (anziché alle visualizzazioni Texture1D/2D/3D/Cube) non sono validi e producono risultati non definiti, inclusa la possibile reimpostazione del dispositivo, anziché restituire i valori predefiniti per le letture o l'eliminazione di scritture. Lo scopo di rimuovere la possibilità per le applicazioni di dipendere dal controllo di accesso all'hardware fuori dai limiti consiste nel consentire ai driver di scegliere di promuovere gli accessi dei descrittori statici agli accessi del descrittore radice se ritengono più efficiente. I descrittori radice non supportano alcun controllo dei limiti.

Se le applicazioni dipendono dal comportamento di accesso sicuro all'accesso alla memoria quando accedono ai descrittori, è necessario contrassegnare gli intervalli di descrittori che accedono a tali descrittori come DESCRIPTORS_VOLATILE.

DATA_VOLATILE

Con questo flag impostato, i dati a cui puntano i descrittori possono essere modificati dalla CPU in qualsiasi momento, ad eccezione del fatto che l'elenco dei comandi o i bundle che associano la tabella del descrittore sono stati inviati e non sono stati completati l'esecuzione. Si tratta dell'unico comportamento supportato di Root Signature versione 1.0.

Il flag è disponibile sia nei flag di intervallo descrittore che nei flag del descrittore radice.

DATA_STATIC_WHILE_SET_AT_EXECUTE

Con questo flag impostato, i dati a cui puntano i descrittori non possono cambiare a partire da quando il descrittore o la tabella descrittore radice sottostante viene impostata su un elenco di comandi/bundle durante l'esecuzione nella sequenza temporale della GPU e termina quando le estrazioni/dispatch successive non fanno più riferimento ai dati.

Prima che sia stata impostata una tabella del descrittore radice o del descrittore nella GPU, questi dati possono essere modificati anche dallo stesso elenco di comandi/bundle. I dati possono anche essere modificati mentre un descrittore radice o una tabella descrittore che punta a tale tabella è ancora impostata nell'elenco dei comandi/bundle, purché i disegni/dispatch che fanno riferimento a tale tabella siano stati completati. Tuttavia, in questo modo è necessario che la tabella del descrittore venga nuovamente rimbalzata nell'elenco dei comandi prima della successiva dereferenziazione del descrittore radice o della tabella descrittore. Ciò consente al driver di sapere che i dati a cui punta un descrittore radice o una tabella descrittore radice sono stati modificati.

La differenza essenziale tra DATA_STATIC_WHILE_SET_AT_EXECUTE e DATA_VOLATILE è con DATA_VOLATILE un driver non è in grado di stabilire se le copie dei dati in un elenco di comandi hanno modificato i dati a cui punta un descrittore, senza eseguire un rilevamento dello stato aggiuntivo. Pertanto, se, ad esempio, un driver può inserire qualsiasi tipo di comando di prelettura dei dati nell'elenco di comandi (per rendere più efficiente l'accesso degli shader ai dati noti, ad esempio), DATA_STATIC_WHILE_SET_AT_EXECUTE informa il driver che deve solo eseguire il prelettura dei dati nel momento in cui è impostato tramite SetGraphicsRootDescriptorTable, SetComputeRootDescriptorTable o uno dei metodi per impostare la visualizzazione buffer costante, visualizzazione risorse shader o visualizzazione di accesso non ordinato.

Per i bundle, la promessa che i dati siano statici mentre impostati in fase di esecuzione si applicano in modo univoco a ogni esecuzione del bundle.

Il flag è disponibile sia nei flag di intervallo descrittore che nei flag del descrittore radice.

DATA_STATIC

Se questo flag è impostato, i dati a cui puntano i descrittori sono stati inizializzati dal momento in cui un descrittore radice o una tabella descrittore che fa riferimento alla memoria è stata impostata su un elenco di comandi/bundle durante la registrazione e i dati non possono essere modificati fino al termine dell'esecuzione dell'elenco di comandi o del bundle per l'ultima volta.

Per i bundle, la durata statica inizia in corrispondenza dell'impostazione del descrittore radice o della tabella del descrittore durante la registrazione del bundle, anziché la registrazione di un elenco di comandi chiamante. Inoltre, una tabella descrittore che punta ai dati statici deve essere impostata nel bundle e non ereditata. È valido per un elenco di comandi usare una tabella descrittore che punta a dati statici impostati in un bundle e restituiti all'elenco di comandi.

Il flag è disponibile sia nei flag di intervallo descrittore che nei flag del descrittore radice.

Combinazione di flag

Al massimo uno dei flag DATA può essere specificato alla volta, ad eccezione degli intervalli di descrittori sampler che non supportano i flag DATA poiché i campionatori non puntano ai dati.

L'assenza di qualsiasi flag DATA per gli intervalli di descrittori SRV e CBV significa che si presuppone un comportamento predefinito di DATA_STATIC_WHILE_SET_AT_EXECUTE. Il motivo per cui viene scelto questo valore predefinito anziché DATA_STATIC è che DATA_STATIC_WHILE_SET_AT_EXECUTE è molto più probabile che sia un valore predefinito sicuro per la maggior parte dei casi, pur ottenendo un'opportunità di ottimizzazione migliore rispetto all'impostazione predefinita per DATA_VOLATILE.

L'assenza di flag DATA per gli intervalli di descrittori UAV significa che si presuppone un comportamento predefinito di DATA_VOLATILE, in genere vengono scritti UAV.

DESCRIPTORS_VOLATILE non può essere combinato con DATA_STATIC, ma può essere combinato con gli altri flag DATA. Il motivo per cui DESCRIPTORS_VOLATILE può essere combinato con DATA_STATIC_WHILE_SET_AT_EXECUTE è che i descrittori volatili richiedono ancora che i descrittori siano pronti durante l'esecuzione dell'elenco di comandi o del bundle e DATA_STATIC_WHILE_SET_AT_EXECUTE stia solo facendo promesse sulla static-ness all'interno di un subset di esecuzione dell'elenco di comandi/bundle.

Riepilogo contrassegni

Nelle tabelle seguenti sono riepilogate le combinazioni di flag che potrebbero essere utilizzate.

Impostazioni di D3D12_DESCRIPTOR_RANGE_FLAGS valide Descrizione
Nessun flag impostato I descrittori sono statici (impostazione predefinita). Presupposti predefiniti per i dati: per SRV/CBV: DATA_STATIC_WHILE_SET_AT_EXECUTE e per UAV: DATA_VOLATILE. Queste impostazioni predefinite per SRV/CBV si adattano in modo sicuro ai modelli di utilizzo per la maggior parte delle firme radice.
DATA_STATIC I descrittori e i dati sono statici. In questo modo si ottimizza il potenziale per l'ottimizzazione dei driver.
DATA_VOLATILE I descrittori sono statici e i dati sono volatili.
DATA_STATIC_WHILE_SET_AT_EXECUTE I descrittori sono statici e i dati sono statici durante l'esecuzione.
DESCRIPTORS_VOLATILE I descrittori sono volatili e vengono effettuate ipotesi predefinite sui dati: per SRV/CBV: DATA_STATIC_WHILE_SET_AT_EXECUTE e per UAV: DATA_VOLATILE.
DESCRIPTORS_VOLATILE | DATA_VOLATILE I descrittori e i dati sono volatili, equivalenti alla firma radice 1.0.
DESCRIPTORS_VOLATILE | DATA_STATIC_WHILE_SET_AT_EXECUTE I descrittori sono volatili, ma si noti che non consentono di modificarli durante l'esecuzione dell'elenco di comandi. È quindi valido combinare la dichiarazione aggiuntiva che i dati sono statici durante l'impostazione tramite la tabella del descrittore radice durante l'esecuzione. I descrittori sottostanti sono statici in modo efficace per più tempo rispetto ai dati che vengono promessi di essere statici.

 

Impostazioni di D3D12_ROOT_DESCRIPTOR_FLAGS valide Descrizione
Nessun flag impostato Presupposti predefiniti per i dati: per SRV/CBV: DATA_STATIC_WHILE_SET_AT_EXECUTE e per UAV: DATA_VOLATILE. Queste impostazioni predefinite per SRV/CBV si adattano in modo sicuro ai modelli di utilizzo per la maggior parte delle firme radice.
DATA_STATIC I dati sono statici, il miglior potenziale per l'ottimizzazione del driver.
DATA_STATIC_WHILE_SET_AT_EXECUTE I dati sono statici durante l'esecuzione.
DATA_VOLATILE Equivalente alla firma radice 1.0.

 

Riepilogo dell'API versione 1.1

Le chiamate API seguenti abilitano la versione 1.1.

Enumerazioni

Queste enumerazioni contengono i flag chiave per specificare il descrittore e la volatilità dei dati.

Strutture

Le strutture aggiornate (dalla versione 1.0) contengono riferimenti ai flag di volatilità/statici.

Funzioni

I metodi elencati di seguito sostituiscono le funzioni D3D12SerializeRootSignature e D3D12CreateRootSignatureDeserializer originali, poiché sono progettate per funzionare su qualsiasi versione della firma radice. Il modulo serializzato viene passato all'API CreateRootSignature . Se uno shader è stato creato con una firma radice, lo shader compilato conterrà già una firma radice serializzata.

Metodi

L'interfaccia ID3D12VersionedRootSignatureDeserializer viene creata per deserializzare la struttura dei dati della firma radice.

Strutture helper

Sono state aggiunte strutture helper per facilitare l'inizializzazione di alcune delle strutture della versione 1.1.

  • CD3DX12_DESCRIPTOR_RANGE1
  • CD3DX12_ROOT_PARAMETER1
  • CD3DX12_STATIC_SAMPLER1
  • CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC

Vedere Strutture e funzioni helper per D3D12.

Conseguenze della violazione dei flag di statica-ness

Il descrittore e i flag di dati descritti in precedenza (nonché le impostazioni predefinite implicite dall'assenza di flag specifici) definiscono una promessa da parte dell'applicazione al driver in merito al comportamento. Se un'applicazione viola la promessa, si tratta di un comportamento non valido: i risultati non sono definiti e potrebbero essere diversi tra driver e hardware diversi.

Il livello di debug include opzioni per convalidare che le applicazioni rispettano le promesse, incluse le promesse predefinite fornite con l'uso della versione 1.1 della firma radice senza impostare alcun flag.

Gestione delle versioni

Quando si compilano firme radice collegate agli shader, per impostazione predefinita i compilatori HLSL più recenti compilano la firma radice alla versione 1.1, mentre i compilatori HLSL precedenti supportano solo la versione 1.0. Si noti che le firme radice 1.1 non funzioneranno nel sistema operativo che non supportano la firma radice 1.1.

La versione della firma radice compilata con uno shader può essere forzata a una determinata versione usando /force_rootsig_ver <version>. La forzatura della versione avrà esito positivo se il compilatore può mantenere il comportamento della firma radice compilata nella versione forzata, ad esempio eliminando i flag non supportati nella firma radice che servono solo a scopo di ottimizzazione, ma non influiscono sul comportamento.

In questo modo un'applicazione può, ad esempio, compilare una firma radice 1.1 in 1.0 e 1.1 durante la compilazione dell'applicazione e selezionare la versione appropriata in fase di esecuzione a seconda del livello di supporto del sistema operativo. Sarebbe tuttavia più efficiente lo spazio per consentire a un'applicazione di compilare le firme radice singolarmente (in particolare se sono necessarie più versioni), separatamente dagli shader. Anche se gli shader non vengono inizialmente compilati con una firma radice collegata, il vantaggio della convalida della firma radice con uno shader può essere mantenuto usando l'opzione del /verifyrootsignature compilatore. In un secondo momento, gli oggetti PSO possono essere creati usando shader che non contengono firme radice durante il passaggio della firma radice desiderata (ad esempio la versione appropriata supportata dal sistema operativo) come parametro separato.

Creazione di una firma radice

Firme radice

Specifica delle firme radice in HLSL