Esecuzione e sincronizzazione degli elenchi di comandi
In Microsoft Direct3D 12 la modalità immediata delle versioni precedenti non è più presente. Al contrario, le app creano elenchi di comandi e bundle e quindi set di record di comandi GPU. Le code dei comandi vengono usate per inviare elenchi di comandi da eseguire. Questo modello consente agli sviluppatori di avere un maggiore controllo sull'utilizzo efficiente sia dell'unità di elaborazione grafica (GPU) che della CPU.
- Panoramica della coda dei comandi
- Inizializzazione di una coda di comandi
- Esecuzione di elenchi di comandi
- Accesso alle risorse da più code di comandi
- Sincronizzazione dell'esecuzione dell'elenco di comandi tramite recinto della coda di comandi
- Sincronizzazione delle risorse accessibili dalle code dei comandi
- Supporto della coda dei comandi per le risorse affiancate
- Argomenti correlati
Panoramica della coda dei comandi
Le code dei comandi direct3D 12 sostituiscono runtime e sincronizzazione del driver dell'invio immediato di lavoro in modalità immediata, precedentemente non esposte allo sviluppatore, con API per gestire in modo esplicito la concorrenza, il parallelismo e la sincronizzazione. Le code dei comandi offrono i miglioramenti seguenti per gli sviluppatori:
- Consente agli sviluppatori di evitare inefficienze accidentali causate dalla sincronizzazione imprevista.
- Consente agli sviluppatori di introdurre la sincronizzazione a un livello superiore in cui la sincronizzazione necessaria può essere determinata in modo più efficiente e accurato. Ciò significa che il runtime e il driver grafico impiegano meno tempo a ingegneria reattiva parallelismo.
- Rende le operazioni dispendiose più esplicite.
Questi miglioramenti consentono o migliorano gli scenari seguenti:
- Maggiore parallelismo: le applicazioni possono usare code più approfondite per i carichi di lavoro in background, ad esempio la decodifica video, quando hanno code separate per il lavoro in primo piano.
- Lavoro della GPU asincrona e con priorità bassa: il modello di coda dei comandi consente l'esecuzione simultanea di operazioni GPU con priorità bassa e atomica che consentono a un thread GPU di utilizzare i risultati di un altro thread non sincronizzato senza bloccare.
- Lavoro di calcolo ad alta priorità: questa progettazione consente scenari che richiedono l'interruzione del rendering 3D per eseguire una piccola quantità di lavoro di calcolo ad alta priorità in modo che il risultato possa essere ottenuto in anticipo per un'ulteriore elaborazione sulla CPU.
Inizializzazione di una coda di comandi
Le code dei comandi possono essere create chiamando ID3D12Device::CreateCommandQueue. Questo metodo accetta un D3D12_COMMAND_LIST_TYPE che indica il tipo di coda da creare e quindi il tipo di comandi che è possibile inviare a tale coda. Tenere presente che i bundle possono essere chiamati solo da elenchi di comandi diretti e non possono essere inviati direttamente a una coda. I tipi di coda supportati sono:
In generale, le code e gli elenchi di comandi DIRECT accettano qualsiasi comando, le code COMPUTE e gli elenchi di comandi accettano comandi di calcolo e copia correlati e le code COPY e gli elenchi di comandi accettano solo comandi di copia.
Esecuzione di elenchi di comandi
Dopo aver registrato un elenco di comandi e aver recuperato la coda dei comandi predefinita o aver creato un nuovo elenco di comandi, eseguire gli elenchi di comandi chiamando ID3D12CommandQueue::ExecuteCommandLists.
Le applicazioni possono inviare elenchi di comandi a qualsiasi coda di comandi da più thread. Il runtime eseguirà il lavoro di serializzazione di queste richieste nell'ordine di invio.
Il runtime convaliderà l'elenco dei comandi inviato e rimuoverà la chiamata a ExecuteCommandLists se una delle restrizioni viene violata. Le chiamate verranno eliminate per i motivi seguenti:
- L'elenco di comandi fornito è un bundle, non un elenco di comandi diretto.
- ID3D12GraphicsCommandList::Close non è stato chiamato nell'elenco dei comandi fornito per completare la registrazione.
- ID3D12CommandAllocator::Reset è stato chiamato sull'allocatore di comando associato all'elenco di comandi dopo la registrazione. Per altre informazioni sugli allocatori dei comandi, vedere Creazione e registrazione di elenchi di comandi e bundle.
- L'isolamento della coda dei comandi indica che un'esecuzione precedente dell'elenco di comandi non è ancora stata completata. I recinti delle code dei comandi sono descritti in dettaglio di seguito.
- Gli stati precedenti e successivi delle query, impostati con le chiamate a ID3D12GraphicsCommandList::BeginQuery e ID3D12GraphicsCommandList::EndQuery, non corrispondono correttamente.
- Gli stati prima e dopo delle barriere di transizione delle risorse non corrispondono correttamente. Per altre informazioni, vedere Uso delle barriere delle risorse per sincronizzare gli stati delle risorse.
Accesso alle risorse da più code di comandi
Esistono due regole imposte dal runtime che limitano l'accesso alle risorse da più code di comandi. Le regole sono le seguenti:
Una risorsa non può essere scritta da più code di comandi contemporaneamente. Quando una risorsa è passata a uno stato scrivibile in una coda, viene considerata di proprietà esclusiva di tale coda e deve passare a uno stato di lettura o COMMON (fare riferimento a D3D12_RESOURCE_STATES) prima di poter accedere a un'altra coda.
Quando si trova in uno stato di lettura, una risorsa può essere letta da più code di comandi contemporaneamente, inclusi i processi, in base allo stato di lettura.
Per altre informazioni sulle restrizioni di accesso alle risorse e sull'uso delle barriere di risorse per sincronizzare l'accesso alle risorse, vedere Uso delle barriere delle risorse per sincronizzare gli stati delle risorse.
Sincronizzazione dell'esecuzione dell'elenco di comandi tramite recinto della coda di comandi
Il supporto per più code di comandi parallele in Direct3D 12 offre maggiore flessibilità e controllo sulla priorità del lavoro asincrono nella GPU. Questa progettazione significa anche che le app devono gestire in modo esplicito la sincronizzazione del lavoro, soprattutto quando gli elenchi di comandi in una coda dipendono dalle risorse gestite da un'altra coda di comandi. Alcuni esempi includono l'attesa del completamento di un'operazione su una coda di calcolo in modo che il risultato possa essere usato per un'operazione di rendering nella coda 3D e in attesa del completamento di un'operazione 3D in modo che un'operazione sulla coda di calcolo possa accedere a una risorsa per la scrittura. Per abilitare la sincronizzazione del lavoro tra code, Direct3D 12 usa il concetto di recinto, rappresentato nell'API dall'interfaccia ID3D12Fence .
Un recinto è un numero intero che rappresenta l'unità di lavoro corrente elaborata. Quando l'app avanza la recinzione, chiamando ID3D12CommandQueue::Signal, il numero intero viene aggiornato. Le app possono controllare il valore di un recinto e determinare se un'unità di lavoro è stata completata per decidere se è possibile avviare un'operazione successiva.
Sincronizzazione delle risorse accessibili dalle code dei comandi
In Direct3D 12 la sincronizzazione dello stato di alcune risorse viene implementata con le barriere delle risorse. In ogni barriera di risorse, un'app dichiara gli stati prima e dopo di una risorsa. Un esempio comune è la transizione di una risorsa tra una visualizzazione risorsa shader a una visualizzazione di destinazione di rendering. Nella maggior parte dei casi, queste barriere alle risorse vengono gestite all'interno degli elenchi di comandi. Quando i livelli di debug sono abilitati, il sistema impone che gli stati prima e dopo di tutte le risorse corrispondano, garantendo che la risorsa sia nello stato corretto per una determinata operazione in una transizione di barriera.
Per altre informazioni sulla sincronizzazione dello stato delle risorse, vedere Uso delle barriere delle risorse per sincronizzare gli stati delle risorse.
Supporto della coda dei comandi per le risorse affiancate
I metodi per la gestione delle risorse affiancate, esposte tramite l'interfaccia ID3D11DeviceContext2 in Direct3D 11, vengono forniti dall'interfaccia ID3D12CommandQueue in Direct3D 12. Questi metodi includono:
Metodo | Descrizione |
---|---|
CopyTileMappings | Copia i mapping da una risorsa affiancata di origine a una risorsa affiancata di destinazione. |
UpdateTileMappings | Aggiornamenti mapping delle posizioni dei riquadri nelle risorse affiancate ai percorsi di memoria in un heap delle risorse. |
Per altre informazioni sull'uso di risorse affiancate nelle app Direct3D 12, vedere Risorse affiancate direct3D11.