Direct3D 11 su 12
D3D11On12 è un meccanismo con cui gli sviluppatori possono usare interfacce e oggetti D3D11 per guidare l'API D3D12. D3D11on12 consente ai componenti scritti usando D3D11 (ad esempio, testo e interfaccia utente D2D) di lavorare insieme ai componenti scritti destinati all'API D3D12. D3D11on12 abilita anche la conversione incrementale di un'applicazione da D3D11 a D3D12, abilitando parti dell'app per continuare a puntare a D3D11 per semplicità, mentre altre destinazioni D3D12 per le prestazioni, pur avendo sempre il rendering completo e corretto. D3D11On12 semplifica l'uso di tecniche di interoperabilità per condividere le risorse e sincronizzare il lavoro tra le due API.
- inizializzazione di D3D11On12
- esempio di utilizzo
- in background
- pulizia
- limitazioni
- API
- argomenti correlati
Inizializzazione di D3D11On12
Per iniziare a usare D3D11On12, il primo passaggio consiste nel creare un dispositivo D3D12 e una coda di comandi. Questi oggetti vengono forniti come input per il metodo di inizializzazione D3D11On12CreateDevice. È possibile considerare questo metodo come la creazione di un dispositivo D3D11 con il tipo di driver immaginario D3D_DRIVER_TYPE_11ON12, dove il driver D3D11 è responsabile della creazione di oggetti e dell'invio di elenchi di comandi all'API D3D12.
Dopo aver creato un dispositivo D3D11 e un contesto immediato, è possibile QueryInterface
fuori dal dispositivo per l'interfaccia ID3D11On12Device. Questa è l'interfaccia primaria usata per l'interoperabilità tra D3D11 e D3D12. Per avere sia il contesto di dispositivo D3D11 che gli elenchi di comandi D3D12 operano sulle stesse risorse, è necessario creare "risorse incapsulate" usando l'API diCreateWrappedResource. Questo metodo "promuove" una risorsa D3D12 per essere comprensibile in D3D11. Una risorsa sottoposta a wrapping inizia nello stato "acquisito", una proprietà modificata dai metodi AcquireWrappedResources e ReleaseWrappedResource s.
Esempio di utilizzo
L'utilizzo tipico di D3D11On12 sarebbe quello di usare D2D per eseguire il rendering di testo o immagini su un buffer back D3D12. Vedere l'esempio D3D11On12 per un esempio di codice. Ecco una struttura approssimativa dei passaggi da eseguire per eseguire questa operazione:
- Creare un dispositivo D3D12 (D3D12CreateDevice) e una catena di scambio D3D12 (CreateSwapChain con un ID3D12CommandQueue come input).
- Creare un dispositivo D3D11On12 usando il dispositivo D3D12 e la stessa coda di comandi dell'input.
- Recuperare i buffer back della catena di scambio e creare risorse di cui è stato eseguito il wrapping D3D11 per ognuna di esse. Lo stato di input usato deve essere l'ultimo modo in cui D3D12 lo usa (ad esempio, RENDER_TARGET) e lo stato di output deve essere il modo in cui D3D12 lo userà al termine di D3D11 (ad esempio PRESENT).
- Inizializzare D2D e fornire le risorse di cui è stato eseguito il wrapping D3D11 in D2D per prepararsi al rendering.
Quindi, in ogni fotogramma, eseguire le operazioni seguenti:
- Eseguire il rendering nel buffer back della catena di scambio corrente usando un elenco di comandi D3D12 ed eseguirlo.
- Acquisire la risorsa di cui è stato eseguito il wrapping del buffer di back corrente (AcquireWrappedResources).
- Eseguire comandi di rendering D2D.
- Rilasciare la risorsa di cui è stato eseguito il wrapping (ReleaseWrappedResources).
- Scaricare il contesto immediato D3D11.
- Present (IDXGISwapChain1::P resent1).
Sfondo
D3D11On12 funziona sistematicamente. Ogni chiamata API D3D11 passa attraverso la convalida di runtime tipica e ne fa il modo per il driver. A livello di driver, lo speciale driver 11on12 registra lo stato e rilascia le operazioni di rendering negli elenchi di comandi D3D12. Questi elenchi di comandi vengono inviati in base alle esigenze(ad esempio, una query GetData
o una risorsa Map
potrebbe richiedere lo scaricamento dei comandi) o come richiesto da Flush. La creazione di un oggetto D3D11 comporta in genere la creazione dell'oggetto D3D12 corrispondente. Alcune operazioni di rendering di funzioni fisse in D3D11, ad esempio GenerateMips
o DrawAuto
, non sono supportate in D3D12 e quindi D3D11On12 le emula usando shader e risorse aggiuntive.
Per l'interoperabilità, è importante comprendere come D3D11On12 interagisce con gli oggetti D3D12 creati e forniti dall'app. Per garantire che il lavoro venga eseguito nell'ordine corretto, è necessario scaricare il contesto immediato D3D11 prima di poter inviare ulteriori operazioni D3D12 a tale coda. È anche importante assicurarsi che la coda assegnata a D3D11On12 sia svuotabile in qualsiasi momento. Ciò significa che eventuali attese sulla coda devono essere soddisfatte, anche se il thread di rendering D3D11 si blocca a tempo indefinito. Prestare attenzione a non accettare una dipendenza da quando D3D11On12 inserisce scaricamenti o attese, in quanto ciò potrebbe cambiare con le versioni future. D3D11On12 tiene traccia e modifica gli stati delle risorse autonomamente. L'unico modo per garantire la coerenza delle transizioni di stato consiste nell'usare le API di acquisizione/rilascio per modificare il rilevamento dello stato in base alle esigenze dell'app.
Pulizia
Per rilasciare una risorsa di cui è stato eseguito il wrapping D3D11On12, è necessario eseguire due operazioni in questo ordine:
- Tutti i riferimenti alla risorsa, incluse le visualizzazioni della risorsa, devono essere rilasciati.
- L'elaborazione della distruzione posticipata deve essere eseguita. Il modo più semplice per assicurarsi che ciò accada consiste nell'richiamare il contesto immediato
Flush
API.
Al termine di entrambi questi passaggi, tutti i riferimenti eseguiti dalla risorsa di cui è stato eseguito il wrapping devono essere rilasciati e la risorsa D3D12 diventa di proprietà esclusiva del componente D3D12. Tenere presente che D3D12 richiede ancora l'attesa del completamento della GPU prima del rilascio completo di una risorsa, quindi assicurarsi di conservare un riferimento sulla risorsa prima di eseguire i due passaggi precedenti, a meno che non si sia già verificato che la GPU non usi più la risorsa.
Tutte le altre risorse o oggetti creati da D3D11On12 verranno puliti al momento appropriato, al termine dell'uso della GPU, usando il meccanismo di distruzione posticipata di D3D11. Tuttavia, se si tenta di rilasciare il dispositivo D3D11On12 stesso mentre la GPU è ancora in esecuzione, la distruzione potrebbe bloccarsi fino al completamento della GPU.
Limitazioni
Il livello D3D11On12 implementa un subset molto grande dell'API D3D11, ma esistono alcune lacune note (oltre ai bug nell'implementazione che possono causare rendering errato).
A partire da Windows 10, versione 1809 (10.0; Build 17763), purché D3D11On12 sia in esecuzione in un driver che supporta il modello shader 6.0 o versione successiva, può eseguire shader che usano interfacce. Nelle versioni precedenti di Windows, la funzionalità delle interfacce dello shader non è implementata in D3D11On12 e il tentativo di usare la funzionalità causerà errori e messaggi di debug.
A partire da Windows 10, versione 1803 (10.0; Build 17134), le catene di scambio sono supportate nei dispositivi D3D11On12. Nelle versioni precedenti di Windows non sono.
D3D11On12 non è stato ottimizzato per le prestazioni. È probabile che si verifichi un sovraccarico medio della CPU rispetto a un driver D3D11 standard, un sovraccarico minimo della GPU ed è noto un sovraccarico significativo della memoria. Pertanto non è consigliabile usare D3D11On12 per scene 3D complesse ed è invece consigliato per scene semplici o rendering 2D.
Api
Le API che costituiscono il livello 11on12 sono descritte in riferimento 11on12.
Argomenti correlati