Modifiche importanti da Direct3D 9 a Direct3D 11
Riepilogo
- Pianificare la porta DirectX
- Modifiche importanti da Direct3D 9 a Direct3D 11
- Mapping delle funzionalità
Questo argomento spiega le differenze di livello alto tra DirectX 9 e DirectX 11.
Direct3D 11 è fondamentalmente lo stesso tipo di API di Direct3D 9, un'interfaccia virtualizzata di basso livello nell'hardware grafico. Consente comunque di eseguire operazioni di disegno grafico su un'ampia gamma di implementazioni hardware. Il layout dell'API grafica è cambiato da Direct3D 9; il concetto di contesto di dispositivo è stato ampliato e un'API è stata aggiunta specificamente per l'infrastruttura grafica. Le risorse archiviate nel dispositivo Direct3D hanno un nuovo meccanismo per il polimorfismo dei dati denominato visualizzazione delle risorse.
Funzioni API principali
In Direct3D 9 era necessario creare un'interfaccia per l'API Direct3D prima di iniziare a utilizzarla. In un gioco UWP (Universal Windows Platform) Direct3D 11 si chiama una funzione statica denominata D3D11CreateDevice per creare il dispositivo e il contesto del dispositivo.
Dispositivi e contesto del dispositivo
Un dispositivo Direct3D 11 rappresenta una scheda grafica virtualizzata. Viene utilizzato per creare risorse in memoria video, ad esempio caricare trame nella GPU, creare viste su risorse di trama e catene di scambio e creare campioni di trama. Per un elenco completo di ciò per cui viene utilizzata l'interfaccia del dispositivo Direct3D 11 vedere ID3D11Device e ID3D11Device1.
Un contesto del dispositivo Direct3D 11 viene utilizzato per impostare lo stato della pipeline e generare comandi di rendering. Ad esempio, una catena di rendering Direct3D 11 utilizza un contesto del dispositivo per configurare la catena di rendering e disegnare la scena (vedere di seguito). Il contesto del dispositivo viene utilizzato per accedere (mappare) alla memoria video utilizzata dalle risorse del dispositivo Direct3D; viene utilizzato anche per aggiornare i dati delle sottorisorse, ad esempio i dati del buffer costante. Per un elenco completo di ciò per cui viene utilizzato il contesto del dispositivo Direct3D 11 vedere ID3D11DeviceContext e ID3D11DeviceContext1. Notare che la maggior parte dei nostri esempi utilizza un contesto immediato per eseguire il rendering direttamente nel dispositivo, ma Direct3D 11 supporta anche contesti di dispositivo differiti, utilizzati principalmente per il multithreading.
In Direct3D 11, l'handle del dispositivo e l'handle del contesto del dispositivo vengono entrambi ottenuti chiamando D3D11CreateDevice. Questo metodo è anche dove si richiede una serie specifica di funzionalità hardware e si recuperano informazioni sui livelli di funzionalità Direct3D supportati dalla scheda grafica. Per maggiori informazioni su dispositivi, contesti del dispositivo e considerazioni sul threading, vedere Introduzione a un dispositivo in Direct3D 11.
Infrastruttura del dispositivo, buffer di frame e visualizzazioni target di rendering
In Direct3D 11, la configurazione dell'adattatore del dispositivo e dell'hardware viene impostata con l'API DXGI (DirectX Graphics Infrastructure) tramite le interfacce COM IDXGIAdapter e IDXGIDevice1. I buffer e altre risorse finestra (visibili o fuori schermo) vengono creati e configurati da interfacce DXGI specifiche; l'implementazione del modello factory IDXGIFactory2 acquisisce risorse DXGI, quali il buffer dei frame. Poiché DXGI possiede la catena di scambio, viene utilizzata un'interfaccia DXGI per presentare frame allo schermo - vedere IDXGISwapChain1.
Utilizzare IDXGIFactory2 per creare una catena di scambio compatibile con il gioco. È necessario creare una catena di scambio per una finestra principale o per la composizione (interoperabilità XAML), invece di creare una catena di scambio per un HWND.
Risorse del dispositivo e viste delle risorse
Direct3D 11 supporta un livello aggiuntivo di polimorfismo sulle risorse di memoria video note come viste. Essenzialmente, dove si dispone di un singolo oggetto Direct3D 9 per una trama, si dispone ora di due oggetti: la risorsa trama, che contiene i dati e la vista delle risorse, che indica come viene utilizzata la vista per il rendering. Una vista basata su una risorsa consente di utilizzare tale risorsa per uno scopo specifico. Ad esempio, una risorsa trama 2D viene creata come ID3D11Texture2D, quindi viene creata una vista di risorsa shader (ID3D11ShaderResourceView) su di essa in modo che possa essere utilizzata come trama in uno shader. È anche possibile creare una vista di target di rendering (ID3D11RenderTargetView) nella stessa risorsa trama 2D in modo che possa essere utilizzata come superficie di disegno. In un altro esempio, gli stessi dati pixel sono rappresentati in 2 formati di pixel diversi utilizzando 2 visualizzazioni separate su una singola risorsa trama.
La risorsa sottostante deve essere creata con proprietà compatibili con il tipo di viste che verranno create da essa. Ad esempio, se viene applicato un ID3D11RenderTargetView a una superficie, tale superficie viene creata con il flag D3D11_BIND_RENDER_TARGET. La superficie deve anche avere un formato di superficie DXGI compatibile con il rendering (vedere DXGI_FORMAT).
La maggior parte delle risorse che si utilizzano per il rendering eredita dall'interfaccia ID3D11Resource, che a sua volta eredita da ID3D11DeviceChild. I buffer di vertici, i buffer di indici, i buffer costanti e gli shader sono tutte risorse Direct3D 11. I layout di input e gli stati del campionatore ereditano direttamente da ID3D11DeviceChild.
Le viste delle risorse utilizzano un valore di enumerazione DXGI_FORMAT per indicare il formato pixel. Non tutti i D3DFMT vengono supportati come DXGI_FORMAT. Ad esempio, non esiste un formato 24bpp RGB in DXGI equivalente a D3DFMT_R8G8B8. Non esistono nemmeno equivalenti BGR per ogni formato RGB (DXGI_FORMAT_R10G10B10A2_UNORM è equivalente a D3DFMT_A2B10G10R10, ma non esiste alcun equivalente diretto a D3DFMT_A2R10G10B10). È consigliabile pianificare la conversione di qualsiasi contenuto in questi formati legacy in formati supportati in fase di realizzazione. Per un elenco completo dei formati DXGI, vedere l'enumerazione DXGI_FORMAT.
Le risorse del dispositivo Direct3D (e le viste delle risorse) vengono create prima del rendering della scena. I contesti del dispositivo vengono utilizzati per configurare la catena di rendering, come illustrato di seguito.
Contesto del dispositivo e catena di rendering
In Direct3D 9 e Direct3D 10.x era presente un singolo oggetto dispositivo Direct3D che gestiva la creazione, lo stato e il disegno delle risorse. In Direct3D 11 l'interfaccia del dispositivo Direct3D gestisce ancora la creazione delle risorse, ma tutte le operazioni di stato e disegno vengono gestite tramite un contesto del dispositivo Direct3D. Ecco un esempio di come viene utilizzato il contesto del dispositivo interfaccia (ID3D11DeviceContext1) per configurare la catena di rendering:
- Impostare e cancellare le viste del target di rendering (e la vista depth stencil)
- Impostare il buffer di vertici, il buffer di indici e il layout di input per lo stadio di input assembler (stadio IA)
- Associare shader di vertici e dipixel alla pipeline
- Associare buffer costanti agli shader
- Associare viste di trama e campionatori allo shader di pixel
- Disegnare la scena
Quando viene chiamato uno dei metodi ID3D11DeviceContext::Draw, la scena viene disegnata nella vista del target di rendering. Al termine, tutto il disegno dell'adattatore DXGI viene utilizzato per presentare il frame completato chiamando IDXGISwapChain1::Present1.
Gestione dello stato
Direct3D 9 gestiva le impostazioni dello stato con una serie ampia di singoli interruttori impostati con i metodi SetRenderState, SetSamplerState e SetTextureStageState. Poiché Direct3D 11 non supporta la pipeline legacy a funzione fissa, SetTextureStageState viene sostituito dalla scrittura di shader di pixel (PS). Non esiste alcun equivalente a un blocco di stato Direct3D 9. Direct3D 11 gestisce invece lo stato tramite l'uso di 4 tipi di oggetti di stato che offrono un modo più semplificato per raggruppare lo stato di rendering.
Ad esempio, invece di utilizzare SetRenderState con D3DRS_ZENABLE, si crea un oggetto DepthStencilState con questa e altre impostazioni di stato correlate e lo si utilizza per modificare lo stato durante il rendering.
Quando si esegue la conversione di applicazioni Direct3D 9 in oggetti di stato, tenere presente che le varie combinazioni di stato sono rappresentate come oggetti di stato non modificabili. Devono essere creati una sola volta e riutilizzati finché sono validi.
Livelli di funzionalità Direct3D
Direct3D possiede un nuovo meccanismo per determinare il supporto hardware denominato livelli di funzionalità. I livelli di funzionalità semplificano l'attività di capire cosa può fare la scheda grafica consentendo di richiedere una serie ben definita di funzionalità GPU. Ad esempio, il livello di funzionalità 9_1 implementa la funzionalità fornita dalle schede grafiche Direct3D 9, incluso il modello shader 2.x. Poiché 9_1 è il livello di funzionalità più basso, è possibile prevedere che tutti i dispositivi supportino uno shader di vertici e uno shader di pixel, che erano gli stessi stadi supportati dal modello di shader programmabile Direct3D 9.
Il gioco utilizzerà D3D11CreateDevice per creare il dispositivo Direct3D e il contesto del dispositivo. Quando si chiama questa funzione, viene fornito un elenco di livelli di funzionalità che il gioco può supportare. Restituirà il livello di funzionalità supportato più alto da tale elenco. Ad esempio, se il gioco può utilizzare trame BC4/BC5 (una funzionalità dell'hardware DirectX 10), includere almeno 9_1 e 10_0 nell'elenco dei livelli di funzionalità supportati. Se il gioco è in esecuzione su hardware DirectX 9 e non è possibile utilizzare trame BC4/BC5, D3D11CreateDevice restituirà 9_1. Il gioco può quindi eseguire il fallback a un formato di trama diverso (e trame più piccole).
Se si decide di estendere il gioco Direct3D 9 per supportare livelli di funzionalità Direct3D più elevati, è preferibile completare prima la conversione del codice grafico Direct3D 9 esistente. Dopo aver eseguito il gioco in Direct3D 11, è più facile aggiungere percorsi di rendering aggiuntivi con grafica avanzata.
Per una spiegazione dettagliata del supporto a livello di funzionalità, vedere Livelli di funzionalità Direct3D. Per un elenco completo delle funzionalità di Direct3D 11, vedere Funzionalità di Direct3D 11.1 e Funzionalità di Direct3D 11.
Livelli di funzionalità e la pipeline programmabile
L'hardware continua a evolversi da Direct3D 9 e sono state aggiunti diversi nuove stadi facoltativi alla pipeline grafica programmabile. La serie di opzioni disponibili per la pipeline grafica varia a seconda del livello di funzionalità Direct3D. Il livello di funzionalità 10.0 include lo stadio shader di geometria con flusso opzionale per il rendering multipass sulla GPU. Il livello di funzionalità 11_0 include lo shader hull e lo shader domain da utilizzare con tassellatura hardware. Il livello di funzionalità 11_0 include anche il supporto completo per gli shader DirectCompute, mentre i livelli di funzionalità 10.x includono solo il supporto per una forma limitata di DirectCompute.
Tutti gli shader vengono scritti in HLSL utilizzando un profilo shader che corrisponde a un livello di funzionalità Direct3D. I profili shader sono compatibili verso l'alto, quindi uno shader HLSL che viene compilato utilizzando vs_4_0_level_9_1 o ps_4_0_level_9_1 funzionerà in tutti i dispositivi. I profili shader non sono compatibili con livello inferiore, quindi uno shader compilato con vs_4_1 funzionerà solo sui dispositivi di livello di funzionalità 10_1, 11_0 o 11_1.
Direct3D 9 gestiva le costanti per gli shader utilizzando una matrice condivisa con SetVertexShaderConstant e SetPixelShaderConstant. Direct3D 11 utilizza buffer costanti, che sono risorse come un buffer di vertici o un buffer di indici. I buffer costanti sono progettati per essere aggiornati in modo efficiente. Anziché organizzare tutti le costanti di shader in una singola matrice globale, è possibile organizzare le costanti in raggruppamenti logici e gestirle tramite uno o più buffer costanti. Quando si trasferisce un gioco Direct3D 9 in Direct3D 11, pianificare per organizzare i buffer costanti in modo da poterli aggiornare in modo appropriato. Ad esempio, raggruppare le costanti shader che non vengono aggiornate a ogni frame in un buffer costante separato, in modo che non sia necessario caricare costantemente i dati nella scheda grafica insieme alle costanti shader più dinamiche.
Nota La maggior parte delle applicazioni Direct3D 9 facevano ampio uso degli shader, ma occasionalmente mescolavano l'uso del comportamento legacy a funzionamento fisso. Notare che Direct3D 11 utilizza esclusivamente un modello di ombreggiatura programmabile. Le funzionalità legacy a funzione fissa di Direct3D 9 sono deprecate.