Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Le catene di scambio controllano la rotazione del buffer nascosto, formando la base dell'animazione grafica.
Panoramica
Il modello di programmazione per le catene di scambio in Direct3D 12 non è identico a quello nelle versioni precedenti di D3D. La praticità della programmazione, ad esempio, di supportare la rotazione automatica delle risorse presente in D3D10 e D3D11 non è più supportata. La rotazione automatica delle risorse consente alle app di eseguire il rendering dello stesso oggetto API mentre la superficie effettiva di cui viene eseguito il rendering cambia ogni fotogramma. Il comportamento delle catene di scambio viene modificato con Direct3D 12 per consentire ad altre funzionalità di Direct3D 12 di avere un sovraccarico della CPU ridotto. La chiave di colore automatica e il multicampionamento non sono supportati, anche se in particolare l'estensione e la rotazione sono ancora.
Durata del buffer
Le app possono archiviare descrittori già creati che fanno riferimento ai buffer back. Ciò è abilitato assicurando che il set di buffer di proprietà di una catena di scambio non cambi mai per la durata della catena di scambio. Il set di buffer restituiti da IDXGISwapChain::GetBuffer non cambia finché non vengono chiamate determinate API:
L'ordine dei buffer restituiti da GetBuffer non cambia mai.
IDXGISwapChain3::GetCurrentBackBufferIndex restituisce l'indice del buffer nascosto corrente all'app.
Effetti di scambio
Gli unici effetti di scambio supportati sono DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL e DXGI_SWAP_EFFECT_FLIP_DISCARD, che richiede che il numero di buffer sia maggiore di uno.
Tip
Per i giochi ottimizzati per una latenza di input minima, creare la swap chain con DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING, quindi chiamare Present(0, DXGI_PRESENT_ALLOW_TEARING). Questo aggira il vsync del compositor e fornisce la latenza minima tra la presentazione e la visualizzazione. In fase di esecuzione, verificare il supporto del tearing chiamando IDXGIFactory5::CheckFeatureSupport con DXGI_FEATURE_PRESENT_ALLOW_TEARING prima di utilizzare questa modalità.
Avvertimento
Un bug comune della cadenza dei fotogrammi consiste nel chiamare Present(1, 0) (vsync-on) senza sincronizzare correttamente il lavoro della CPU con la fence della GPU. Ciò fa sì che la CPU si porti avanti, creando una coda di frame che aumenta la latenza di input. Usare sempre una fence basata sul conteggio dei fotogrammi per limitare il numero di frame della CPU in corso di elaborazione (in genere al numero di buffer meno uno).
Transizione tra modalità a schermo intero e finestra
Direct3D 12 non supporta la modalità esclusiva a schermo intero (FSE). Al contrario, quando un gioco è l'unica applicazione visibile sullo schermo, il sistema operativo usa una strategia denominata ottimizzazioni a schermo intero (FSO) per ottenere un effetto simile a FSE senza gli svantaggi delle prestazioni. Per ulteriori informazioni sull'FSO, consulta Demystifying Fullscreen Optimisations.
Direct3D 12 mantiene la restrizione che le applicazioni devono chiamare ResizeBuffers dopo la transizione tra le modalità finestra e a schermo intero (le catene di scambio del modello flip-model D3D11 hanno le stesse restrizioni).
Le transizioni IDXGISwapChain::SetFullscreenState non modificano il set di buffer visibili dall'app nella catena di scambio. Solo i ResizeBuffers e ResizeTarget chiamate creano o eliminano buffer visibili dall'app. Tuttavia, in Direct3D 12 IDXGISwapChain::SetFullscreenState non entra in modalità esclusiva a schermo intero e cambia semplicemente risoluzioni e frequenze di aggiornamento per consentire ottimizzazioni a schermo intero. Queste modifiche possono essere apportate da un'app senza l'uso di questo metodo
Quando viene chiamato IDXGISwapChain::Present o IDXGISwapChain1::Present, il back buffer da presentare deve trovarsi nello stato D3D12_RESOURCE_STATE_PRESENT. Il presente avrà esito negativo con DXGI_ERROR_INVALID_CALL se questo non è il caso.
Le catene di scambio a schermo intero continuano ad avere la restrizione che SetFullscreenState(FALSE, NULL) deve essere chiamata prima del rilascio finale della catena di scambio. SetFullscreenState(FALSE) ha esito positivo nelle catene di scambio in esecuzione su dispositivi Direct3D 12.
Le operazioni presenti si verificano nella coda 3D fornita durante la creazione della porta di scambio e le app sono libere di presentare simultaneamente più catene di scambio e registrare ed eseguire elenchi di comandi.
Quando la parte finale del lavoro grafico (ad esempio la post-elaborazione dei frame) viene eseguita su una coda di calcolo, oppure non coinvolge la coda grafica del dispositivo, può essere utile creare una seconda coda 3D su cui effettuare la presentazione, evitando che la latenza della presentazione ritardi l'inizio del frame successivo.
Esempio
Il codice di esempio seguente è presente nel ciclo di rendering principale:
Avvertimento
L'esempio seguente è semplificato per maggiore chiarezza. Un ciclo di gioco pronto per la produzione dovrebbe disaccoppiare gli aggiornamenti della simulazione dalla frequenza di rendering, ad esempio usando un timestep fisso per la simulazione mentre esegue il rendering il più velocemente possibile, e usare una fence per limitare i frame in volo. Senza una limitazione del numero di fotogrammi in volo, Present può riuscire immediatamente nelle catene di scambio con modello flip, consentendo alla CPU di accodare i fotogrammi senza limiti e aumentare la latenza di input.
void Present()
{
m_swapChain->Present(0, m_presentFlags);
m_backBufferIndex = (m_backBufferIndex + 1) % m_backBufferCount;
}
Creazione di catene di scambio
Quando si usano le chiamate CreateSwapChainForHwnd, CreateSwapChainForCoreWindow o CreateSwapChainForComposition, si noti che il parametro pDevice richiede in realtà un puntatore a una coda di comandi diretta in Direct3D 12, anziché un dispositivo.
Presentazione in Windows 7
Quando si usa Direct3D 12 come destinazione su Windows 7, i tipi DXGI necessari per Direct3D 12 non sono disponibili, quindi è necessario usare l'interfaccia ID3D12CommandQueueDownLevel fornita da D3D12On7 (ottenuta interrogando la coda di comandi diretta) per eseguire la presentazione.
Fornisci un elenco di comandi aperto al metodo presente di Windows 7, che verrà quindi usato, chiuso e inviato automaticamente al dispositivo. Devi fornire un buffer nascosto che deve essere creato dall'app, deve essere una risorsa di cui è stato eseguito il commit, deve essere a campione singolo e deve essere uno dei formati seguenti.
- DXGI_FORMAT_R16G16B16A16_FLOAT
- DXGI_FORMAT_R10G10B10A2_UNORM
- DXGI_FORMAT_R8G8B8A8_UNORM
- DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
- DXGI_FORMAT_B8G8R8X8_UNORM
- DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM
- DXGI_FORMAT_B8G8R8A8_UNORM
- DXGI_FORMAT_B8G8R8A8_UNORM_SRGB