Introduzione a un dispositivo in Direct3D 11
Il modello a oggetti Direct3D 11 separa la creazione e la funzionalità di rendering delle risorse in un dispositivo e in uno o più contesti; questa separazione è progettata per facilitare il multithreading.
Dispositivo
Un dispositivo viene usato per creare risorse ed enumerare le funzionalità di una scheda di visualizzazione. In Direct3D 11 un dispositivo è rappresentato con un'interfaccia ID3D11Device .
Ogni applicazione deve avere almeno un dispositivo, la maggior parte delle applicazioni crea un solo dispositivo. Creare un dispositivo per uno dei driver hardware installati nel computer chiamando D3D11CreateDevice o D3D11CreateDeviceAndSwapChain e specificare il tipo di driver con il flag D3D_DRIVER_TYPE . Ogni dispositivo può usare uno o più contesti di dispositivo, a seconda della funzionalità desiderata.
Contesto di dispositivo
Un contesto di dispositivo contiene la circostanza o l'impostazione in cui viene usato un dispositivo. In particolare, un contesto di dispositivo viene usato per impostare lo stato della pipeline e generare comandi di rendering usando le risorse di proprietà di un dispositivo. Direct3D 11 implementa due tipi di contesti di dispositivo, uno per il rendering immediato e l'altro per il rendering posticipato; entrambi i contesti sono rappresentati con un'interfaccia ID3D11DeviceContext .
Contesto immediato
Il rendering di un contesto immediato viene eseguito direttamente al driver. Ogni dispositivo ha uno e un solo contesto immediato che può recuperare i dati dalla GPU. Un contesto immediato può essere usato per eseguire immediatamente il rendering (o riprodurre) un elenco di comandi.
Esistono due modi per ottenere un contesto immediato:
- Chiamando D3D11CreateDevice o D3D11CreateDeviceAndSwapChain.
- Chiamando ID3D11Device::GetImmediateContext.
Contesto posticipato
Un contesto posticipato registra i comandi GPU in un elenco di comandi. Un contesto posticipato viene usato principalmente per il multithreading e non è necessario per un'applicazione a thread singolo. Un contesto posticipato viene in genere usato da un thread di lavoro anziché dal thread di rendering principale. Quando si crea un contesto posticipato, non eredita alcuno stato dal contesto immediato.
Per ottenere un contesto posticipato, chiamare ID3D11Device::CreateDeferredContext.
Qualsiasi contesto, immediato o posticipato, può essere usato in qualsiasi thread, purché il contesto venga usato solo in un thread alla volta.
Considerazioni sul threading
Questa tabella evidenzia le differenze nel modello di threading in Direct3D 11 rispetto alle versioni precedenti di Direct3D.
Differenze tra Direct3D 11 e le versioni precedenti di Direct3D:
Tutti i metodi di interfaccia ID3D11Device sono a thread libero, il che significa che è sicuro avere più thread chiamare contemporaneamente le funzioni.
- Tutte le interfacce derivate da ID3D11DeviceChild (ID3D11Buffer, ID3D11Query e così via) sono a thread libero.
- Direct3D 11 suddivide la creazione e il rendering delle risorse in due interfacce. Map, Unmap, Begin, End e GetData vengono implementati in ID3D11DeviceContext perché ID3D11Device definisce fortemente l'ordine delle operazioni. Le interfacce ID3D11Resource e ID3D11Asynchronous implementano anche metodi per le operazioni a thread libero.
- I metodi ID3D11DeviceContext (ad eccezione di quelli esistenti in ID3D11DeviceChild) non sono a thread libero, ovvero richiedono il threading singolo. Un solo thread può chiamare in modo sicuro uno dei relativi metodi (Draw, Copy, Map e così via) alla volta.
- In generale, il threading libero riduce al minimo il numero di primitive di sincronizzazione usate e la relativa durata. Tuttavia, un'applicazione che usa la sincronizzazione mantenuta per molto tempo può influire direttamente sulla concorrenza prevista da un'applicazione.