Swapchains

Swapchains steuern die Drehung des Hintergrundpuffers und bilden die Grundlage der Grafikanimation.

Überblick

Das Programmiermodell für Swapchains in Direct3D 12 ist nicht identisch mit dem in früheren D3D-Versionen. Der Programmierkomfort – zum Beispiel die Unterstützung der automatischen Ressourcenrotation, die in D3D10 und D3D11 vorhanden war – wird nicht mehr geboten. Die automatische Ressourcenrotation ermöglichte es Apps, dasselbe API-Objekt zu rendern, während sich die tatsächlich gerenderte Oberfläche mit jedem Frame änderte. Das Verhalten von Swapchains wird mit Direct3D 12 geändert, um anderen Features von Direct3D 12 einen geringen CPU-Aufwand zu ermöglichen. Automatischer Farbschlüssel und Multisampling werden nicht unterstützt, auch wenn bemerkenswerterweise Stretching und Rotation weiterhin unterstützt werden.

Pufferlebensdauer

Apps dürfen vordefinierte Deskriptoren speichern, die auf Hintergrundpuffer verweisen. Dadurch wird sichergestellt, dass sich der Satz von Puffern im Besitz einer Swapchain für die Lebensdauer der Swapchain nie ändert. Der Satz von Puffern, die von IDXGISwapChain::GetBuffer zurückgegeben werden, ändert sich erst, wenn bestimmte APIs aufgerufen werden:

Die Reihenfolge der Puffer, die von GetBuffer zurückgegeben werden, ändert sich nie.

IDXGISwapChain3::GetCurrentBackBufferIndex den Index des aktuellen Hintergrundpuffers an die App zurückgibt.

Swap-Effekte

Die einzigen unterstützten Swapeffekte sind DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL und DXGI_SWAP_EFFECT_FLIP_DISCARD, was erfordert, dass die Pufferanzahl größer als eins ist.

Tip

Erstellen Sie für Spiele, bei denen eine minimale Eingabelatenz angestrebt wird, die Swapchain mit DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING, und rufen Sie dann Present(0, DXGI_PRESENT_ALLOW_TEARING) auf. Dadurch wird die VSync des Kompositors umgangen und die geringstmögliche Latenz zwischen Präsentation und Anzeige ermöglicht. Überprüfen Sie zur Laufzeit die Tearing-Unterstützung, indem Sie IDXGIFactory5::CheckFeatureSupport mit DXGI_FEATURE_PRESENT_ALLOW_TEARING aufrufen, bevor Sie diesen Pfad verwenden.

Warnung

Ein häufiger Frame-Pacing-Fehler besteht darin, Present(1, 0) (vsync-on) aufzurufen, ohne die CPU-Arbeit ordnungsgemäß mit dem GPU-Fence zu synchronisieren. Dies führt dazu, dass die CPU vorausläuft und eine Framewarteschlange erstellt, die die Eingabelatenz erhöht. Verwenden Sie immer eine Framezahlgrenze, um CPU-Frames in Flight zu begrenzen (in der Regel auf die Pufferanzahl minus 1).

Übergang zwischen Fenstermodus und Vollbildmodus

Direct3D 12 unterstützt keinen exklusiven Vollbildmodus (FullScreen Exclusive Mode, FSE). Wenn ein Spiel die einzige sichtbare Anwendung auf dem Bildschirm ist, verwendet das Betriebssystem stattdessen eine Strategie namens Vollbildoptimierungen (FullScreen Optimizations, FSO), um einen ähnlichen Effekt wie FSE ohne leistungsbedingte Nachteile zu erzielen. Weitere Informationen zu FSO finden Sie unter Demystifizieren von Vollbildoptimierungen.

Direct3D 12 behält die Einschränkung bei, dass Anwendungen nach dem Wechsel zwischen Fenster- und Vollbildmodus ResizeBuffers aufrufen müssen (D3D11-Swapchains mit Flip-Modell unterliegen denselben Einschränkungen).

Die IDXGISwapChain::SetFullscreenState-Übergänge ändern nicht die Menge der für die App sichtbaren Puffer der Swapchain. Nur die ResizeBuffers und ResizeTarget-aufrufe erstellen oder zerstören App-sichtbare Puffer. In Direct3D 12 IDXGISwapChain::SetFullscreenState wechselt jedoch nicht in den exklusiven Vollbildmodus und ändert einfach Auflösungen und Aktualisierungsraten, um Vollbildoptimierungen zu ermöglichen. Diese Änderungen können von einer App ohne die Verwendung dieser Methode vorgenommen werden.

Wenn IDXGISwapChain::Present oder IDXGISwapChain1::Present aufgerufen wird, muss sich der darzustellende Backbuffer im Zustand D3D12_RESOURCE_STATE_PRESENT befinden. "Present" schlägt mit DXGI_ERROR_INVALID_CALL fehl, wenn dies nicht der Fall ist.

Vollbild-Swapchains unterliegen weiterhin der Einschränkung, dass SetFullscreenState(FALSE, NULL) vor der endgültigen Freigabe der Swapchain aufgerufen werden muss. SetFullscreenState(FALSE) ist bei Swapchains erfolgreich, die auf Direct3D 12-Geräten ausgeführt werden.

Aktuelle Vorgänge treten in der 3D-Warteschlange auf, die bei der Swapchainerstellung bereitgestellt wird, und Apps können mehrere Swapchains gleichzeitig präsentieren und Befehlslisten aufzeichnen und ausführen.

Wenn der letzte Teil der Grafikverarbeitung (z. B. die Nachbearbeitung des Frames) in einer Compute-Warteschlange ausgeführt wird oder die Grafikwarteschlange des Geräts nicht genutzt wird, kann es von Vorteil sein, eine zweite 3D-Warteschlange zum Präsentieren zu erstellen. So wird verhindert, dass die Präsentationslatenz den Start des nächsten Frames verzögert.

Beispiel

Der folgende Beispielcode wäre in der Hauptrenderingschleife vorhanden:

Warnung

Das folgende Beispiel wird zur Übersichtlichkeit vereinfacht. Eine Produktionsspielschleife sollte Simulationsupdates von der Renderhäufigkeit entkoppeln, zum Beispiel, indem sie einen festen Zeitschritt für die Simulation verwenden, während sie so schnell wie möglich gerendert werden, und eine Obergrenze verwenden, um Frames in Flight zu begrenzen. Ohne Frame-Flight-Begrenzung kann eine Präsentation sofort auf Flip-Modell-Swapchains erfolgreich sein, sodass die CPU Frames ungebunden in die Warteschlange stellen kann und die Eingabelatenz überschreitet.

void Present()
{
    m_swapChain->Present(0, m_presentFlags);
    m_backBufferIndex = (m_backBufferIndex + 1) % m_backBufferCount;
}

Erstellen von Swapchains

Wenn Sie die CreateSwapChainForHwnd, CreateSwapChainForCoreWindowoder CreateSwapChainForComposition Aufrufe verwenden, beachten Sie, dass der pDevice Parameter tatsächlich einen Zeiger auf eine direkte Befehlswarteschlange in Direct3D 12 erfordert und kein Gerät.

Präsentation unter Windows 7

Wenn Sie Direct3D 12 unter Windows 7 als Ziel verwenden, sind die erforderlichen DXGI-Typen für Direct3D 12 nicht vorhanden. Daher müssen Sie zum Präsentieren die von D3D12On7 bereitgestellte ID3D12CommandQueueDownLevel verwenden, die über die direkte Befehlswarteschlange abgefragt wird.

Sie stellen eine offene Befehlsliste für die vorhandene Windows 7-Methode bereit, die dann für Sie verwendet, geschlossen und automatisch an das Gerät übermittelt wird. Sie müssen einen Hintergrundpuffer bereitstellen, der von der App erstellt worden sein muss, eine fest zugewiesene Ressource sein muss, einem einfachen Sampling unterzogen worden sein muss und eines der folgenden Formate haben muss.

  • 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