DXGI–Übersicht

Microsoft DirectX Graphics Infrastructure (DXGI) erkennt an, dass sich einige Teile von Grafiken langsamer entwickeln als andere. Das primäre Ziel von DXGI besteht darin, Aufgaben auf niedriger Ebene zu verwalten, die unabhängig von der DirectX-Grafiklaufzeit sein können. DXGI bietet ein gemeinsames Framework für zukünftige Grafikkomponenten; Die erste Komponente, die DXGI nutzt, ist Microsoft Direct3D 10.

In früheren Versionen von Direct3D waren Aufgaben auf niedriger Ebene wie die Enumeration von Hardwaregeräten, das Darstellen gerenderter Frames für eine Ausgabe, die Steuerung von Gamma und das Verwalten eines Vollbildübergangs in der Direct3D-Runtime enthalten. Diese Aufgaben werden jetzt in DXGI implementiert.

DXGI dient der Kommunikation mit dem Kernelmodustreiber und der Systemhardware, wie im folgenden Diagramm dargestellt.

Diagramm der Kommunikation zwischen Anwendungen, dxgi und Treibern und Hardware

Eine Anwendung kann direkt auf DXGI zugreifen oder die Direct3D-APIs in D3D11_1.h, D3D11.h, D3D10_1.h oder D3D10.h aufrufen, die die Kommunikation mit DXGI für Sie übernimmt. Sie können direkt mit DXGI arbeiten, wenn Ihre Anwendung Geräte auflisten oder steuern muss, wie Daten einer Ausgabe angezeigt werden.

Dieses Thema enthält folgende Abschnitte:

So sehen Sie, welche Formate von Direct3D 11-Hardware unterstützt werden:

Aufzählen von Adaptern

Ein Adapter ist eine Abstraktion der Hardware und der Softwarefunktion Ihres Computers. Es gibt in der Regel viele Adapter auf Ihrem Computer. Einige Geräte sind in Hardware implementiert (z. B. Ihre Video-Karte), andere sind in Software implementiert (z. B. direct3D-Referenzrasterer). Adapter implementieren Funktionen, die von einer Grafikanwendung verwendet werden. Das folgende Diagramm zeigt ein System mit einem einzelnen Computer, zwei Adaptern (Grafikkarten) und drei Ausgabemonitoren.

Abbildung eines Computers mit zwei Grafikkarten und drei Monitoren

Beim Aufzählen dieser Hardwareelemente erstellt DXGI eine IDXGIOutput1-Schnittstelle für jede Ausgabe (oder jeden Monitor) und eine IDXGIAdapter2-Schnittstelle für jeden Video-Karte (auch wenn es sich um ein Video handelt, Karte in eine Hauptplatine integriert ist). Die Enumeration erfolgt mithilfe eines IDXGIFactory-Schnittstellenaufrufs , IDXGIFactory::EnumAdapters, um einen Satz von IDXGIAdapter-Schnittstellen zurückzugeben, die die Videohardware darstellen.

DXGI 1.1 hat die IDXGIFactory1-Schnittstelle hinzugefügt. IDXGIFactory1::EnumAdapters1 gibt einen Satz von IDXGIAdapter1-Schnittstellen zurück, der die Videohardware darstellt.

Wenn Sie bestimmte Videohardwarefunktionen auswählen möchten, wenn Sie Direct3D-APIs verwenden, empfiehlt es sich, die Funktion D3D11CreateDevice oder D3D11CreateDeviceAndSwapChain mit jedem Adapterhandle und der möglichen Hardwarefeatureebene iterativ aufzurufen. Diese Funktion ist erfolgreich, wenn die Featureebene vom angegebenen Adapter unterstützt wird.

Neue Informationen zum Auflisten von Adaptern für Windows 8

Ab Windows 8 ist immer ein Adapter namens "Microsoft Basic Render Driver" vorhanden. Dieser Adapter verfügt über eine VendorId von 0x1414 und eine DeviceID von 0x8c. Für diesen Adapter ist auch der DXGI_ADAPTER_FLAG_SOFTWARE-Wert im Flags-Element seiner DXGI_ADAPTER_DESC2-Struktur festgelegt. Dieser Adapter ist ein reines Rendergerät ohne Anzeigeausgaben. DXGI gibt nie DXGI_ERROR_DEVICE_REMOVED für diesen Adapter zurück.

Wenn der Anzeigetreiber eines Computers nicht funktioniert oder deaktiviert ist, wird der primäre Adapter (NULL) des Computers möglicherweise auch als "Microsoft Basic Render Driver" bezeichnet. Dieser Adapter verfügt jedoch über Ausgaben und ist nicht der DXGI_ADAPTER_FLAG_SOFTWARE Wert festgelegt. Das Betriebssystem und die Apps verwenden diesen Adapter standardmäßig. Wenn ein Anzeigetreiber installiert oder aktiviert ist, können Apps DXGI_ERROR_DEVICE_REMOVED für diesen Adapter empfangen und müssen die Adapter dann erneut aufzählen.

Wenn der primäre Anzeigeadapter eines Computers der "Microsoft Basic Display Adapter" (WARP-Adapter ) ist, verfügt dieser Computer auch über einen zweiten Adapter. Dieser zweite Adapter ist das reine Rendergerät, das über keine Anzeigeausgaben verfügt und für das DXGI nie DXGI_ERROR_DEVICE_REMOVED zurückgibt.

Wenn Sie WARP zum Rendern, Berechnen oder anderen Aufgaben mit langer Ausführung verwenden möchten, wird empfohlen, das reine Rendergerät zu verwenden. Sie können einen Zeiger auf das reine Rendergerät abrufen, indem Sie die IDXGIFactory1::EnumAdapters1-Methode aufrufen. Sie erstellen auch das reine Rendergerät, wenn Sie D3D_DRIVER_TYPE_WARP im DriverType-Parameter von D3D11CreateDevice angeben, da das WARP-Gerät auch den rein rendernden WARP-Adapter verwendet.

Präsentation

Die Aufgabe Ihrer Anwendung besteht darin, Frames zu rendern und DXGI aufzufordern, diese Frames der Ausgabe anzuzeigen. Wenn die Anwendung über zwei Puffer verfügt, kann sie einen Puffer rendern, während ein anderer angezeigt wird. Die Anwendung benötigt möglicherweise mehr als zwei Puffer, abhängig von der Zeit, die zum Rendern eines Frames oder der gewünschten Framerate für die Präsentation benötigt wird. Der Satz von Puffern, die erstellt werden, wird als Swap chain bezeichnet, wie hier gezeigt.

Abbildung einer Swapchain

Eine Swap chain verfügt über einen Frontpuffer und einen oder mehrere Backpuffer. Jede Anwendung erstellt eine eigene Swapchain. Um die Geschwindigkeit der Darstellung der Daten in einer Ausgabe zu maximieren, wird fast immer eine Swapchain im Speicher eines Anzeigeuntersystems erstellt, wie in der folgenden Abbildung dargestellt.

Abbildung eines Anzeigeuntersystems

Das Display-Untersystem (das oft ein Video-Karte ist, aber auf einer Hauptplatine implementiert werden könnte) enthält eine GPU, einen digital-analogen Konverter (DAC) und Arbeitsspeicher. Die Swapchain wird innerhalb dieses Speichers zugeordnet, um die Präsentation sehr schnell zu gestalten. Das Anzeigeuntersystem stellt die Daten im Frontpuffer der Ausgabe dar.

Eine Swapchain wird so eingerichtet, dass sie im Vollbild- oder Fenstermodus zeichnen kann. Dadurch entfällt die Notwendigkeit, zu wissen, ob eine Ausgabe im Fenster- oder Vollbildmodus ausgeführt wird. Eine Vollbildmodus-Swapchain kann die Leistung optimieren, indem die Anzeigeauflösung gewechselt wird.

Erstellen einer Swapchain

Unterschiede zwischen Direct3D 9 und Direct3D 10: Direct3D 10 ist die erste Grafikkomponente, die DXGI verwendet. DXGI weist einige unterschiedliche Swap chain-Verhaltensweisen auf.
  • In DXGI ist eine Swapchain an ein Fenster gebunden, wenn die Swapchain erstellt wird. Diese Änderung verbessert die Leistung und spart Arbeitsspeicher. In früheren Versionen von Direct3D konnte die Swap chain das Fenster ändern, an das die Swapchain gebunden ist.
  • In DXGI ist eine Swapchain bei der Erstellung an ein Renderinggerät gebunden. Das Geräteobjekt, das die Direct3D-Erstellung von Gerätefunktionen zurückgeben, implementiert die IUnknown-Schnittstelle . Sie können QueryInterface aufrufen, um die entsprechende IDXGIDevice2-Schnittstelle des Geräts abzufragen. Eine Änderung am Renderinggerät erfordert, dass die Swapchain neu erstellt wird.
  • In DXGI sind die verfügbaren Tauscheffekte DXGI_SWAP_EFFECT_DISCARD und DXGI_SWAP_EFFECT_SEQUENTIAL. Ab Windows 8 ist auch der DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL Tauscheffekt verfügbar. Die folgende Tabelle zeigt eine Zuordnung von Direct3D 9 zu DXGI-Swapeffektdefinitionen.

    D3D9-Tauscheffekt DXGI-Tauscheffekt
    D3DSWAPEFFECT_DISCARD DXGI_SWAP_EFFECT_DISCARD
    D3DSWAPEFFECT_COPY DXGI_SWAP_EFFECT_SEQUENTIAL mit 1 Puffer
    D3DSWAPEFFECT_FLIP DXGI_SWAP_EFFECT_SEQUENTIAL mit 2 oder mehr Puffern
    D3DSWAPEFFECT_FLIPEX DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL mit 2 oder mehr Puffern

Die Puffer einer Swapchain werden in einer bestimmten Größe und in einem bestimmten Format erstellt. Die Anwendung gibt diese Werte an (oder Sie können die Größe vom Zielfenster erben) beim Start und kann sie optional ändern, wenn sich die Fenstergröße als Reaktion auf Benutzereingaben- oder Programmereignisse ändert.

Nachdem Sie die Swapchain erstellt haben, möchten Sie in der Regel Bilder in ihr rendern. Hier sehen Sie ein Codefragment, das einen Direct3D-Kontext zum Rendern in einer Swap chain einrichtigt. Dieser Code extrahiert einen Puffer aus der Swapchain, erstellt eine render-target-Ansicht aus diesem Puffer und legt sie dann auf dem Gerät fest:

ID3D11Resource * pBB;
ThrowFailure( pSwapChain->GetBuffer(0, __uuidof(pBB),    
  reinterpret_cast<void**>(&pBB)), "Couldn't get back buffer");
ID3D11RenderTargetView * pView;
ThrowFailure( pD3D11Device->CreateRenderTargetView(pBB, NULL, &pView), 
  "Couldn't create view" );
pD3D11DeviceContext->OMSetRenderTargets(1, &pView, 0);
        

Nachdem Ihre Anwendung einen Frame in einen Swap-Chain-Puffer gerendert hat, rufen Sie IDXGISwapChain1::P resent1 auf. Die Anwendung kann dann das nächste Bild rendern.

Pflege und Fütterung der Wechselkette

Rufen Sie nach dem Rendern des Bilds IDXGISwapChain1::P resent1 auf, und rendern Sie das nächste Bild. Das ist der Umfang Ihrer Verantwortung.

Wenn Sie zuvor IDXGIFactory::MakeWindowAssociation aufgerufen haben, kann der Benutzer die Alt-Enter Tastenkombination drücken, und DXGI wechselt Ihre Anwendung zwischen Fenstermodus und Vollbildmodus. IDXGIFactory::MakeWindowAssociation wird empfohlen, da ein Standardsteuerungsmechanismus für den Benutzer dringend erwünscht ist.

Sie müssen zwar nicht mehr Code schreiben als beschrieben, aber mit einigen einfachen Schritten können Ihre Anwendung reaktionsfähiger werden. Der wichtigste Aspekt ist die Größenänderung der Puffer der Swapchain als Reaktion auf die Größenänderung des Ausgabefensters. Natürlich besteht die beste Route der Anwendung darin, auf WM_SIZE zu reagieren und IDXGISwapChain::ResizeBuffers aufzurufen, wobei die in den Parametern der Nachricht enthaltene Größe übergeben wird. Dieses Verhalten sorgt natürlich dafür, dass Ihre Anwendung gut auf den Benutzer reagiert, wenn er die Rahmen des Fensters zieht, aber es ist auch genau das, was einen reibungslosen Vollbildübergang ermöglicht. Ihr Fenster erhält eine WM_SIZE Nachricht, wenn ein solcher Übergang stattfindet, und das Aufrufen von IDXGISwapChain::ResizeBuffers ist die Chance der Swap chain, den Speicher der Puffer für eine optimale Präsentation neu zuzuweisen. Aus diesem Grund muss die Anwendung alle Verweise freigeben, die auf den vorhandenen Puffern vorhanden sind, bevor IDXGISwapChain::ResizeBuffers aufgerufen wird.

Ein Fehler beim Aufrufen von IDXGISwapChain::ResizeBuffers als Reaktion auf den Wechsel in den Vollbildmodus (natürlich als Reaktion auf WM_SIZE) kann die Optimierung des Flippings ausschließen, wobei DXGI einfach den angezeigten Puffer austauschen kann, anstatt die Daten eines Vollbildbildschirms zu kopieren.

IDXGISwapChain1::P resent1 informiert Sie, wenn Ihr Ausgabefenster über DXGI_STATUS_OCCLUDED vollständig verworren ist. In diesem Fall wird empfohlen, dass Ihre Anwendung in den Standbymodus wechselt (durch Aufrufen von IDXGISwapChain1::P resent1 mit DXGI_PRESENT_TEST), da Ressourcen, die zum Rendern des Frames verwendet werden, verschwendet werden. Die Verwendung von DXGI_PRESENT_TEST verhindert, dass Daten während der Okklusionsprüfung angezeigt werden. Sobald IDXGISwapChain1::P resent1 S_OK zurückgibt, sollten Sie den Standbymodus beenden. Verwenden Sie den Rückgabecode nicht, um in den Standbymodus zu wechseln, da die Swapchain nicht auf den Vollbildmodus verzichten kann.

Die Direct3D 11.1-Runtime, die ab Windows 8 verfügbar ist, stellt eine Flip-Model-Swapchain bereit (d. h. eine Swapchain, die den DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL Wert im SwapEffect-Member von DXGI_SWAP_CHAIN_DESC oder DXGI_SWAP_CHAIN_DESC1 festgelegt hat). Wenn Sie Frames einer Ausgabe mit einer Flip-Model-Swapchain präsentieren, hebt DXGI die Bindung des Rückpuffers von allen Pipelinezustandsspeicherorten auf, z. B. einem Renderziel für die Ausgabezusammenführung, mit dem in den Rückpuffer 0 geschrieben wird. Daher wird empfohlen, ID3D11DeviceContext::OMSetRenderTargets direkt vor dem Rendern in den Backpuffer aufzurufen. Rufen Sie beispielsweise OMSetRenderTargets nicht auf, und führen Sie dann Compute-Shaderarbeiten aus, die am Ende kein Rendering für die Ressource ausführen. Weitere Informationen zu Flipmodell-Swapchains und ihren Vorteilen finden Sie unter DXGI Flip Model.

Hinweis

In Direct3D 10 und Direct3D 11 müssen Sie IDXGISwapChain::GetBuffer nicht aufrufen, um den Puffer 0 abzurufen, nachdem Sie IDXGISwapChain1::P resent1 aufgerufen haben, da sich die Identitäten der Backpuffer ändern. Dies geschieht nicht in Direct3D 12, und Ihre Anwendung muss stattdessen Pufferindizes manuell nachverfolgen.

Behandeln der Fenstergröße

Sie können die IDXGISwapChain::ResizeBuffers-Methode verwenden, um die Fenstergröße zu ändern. Bevor Sie ResizeBuffers aufrufen, müssen Sie alle ausstehenden Verweise auf die Puffer der Swapchain freigeben. Das Objekt, das in der Regel einen Verweis auf den Puffer einer Swapchain enthält, ist eine Render-Target-Ansicht.

Der folgende Beispielcode zeigt, wie ResizeBuffers aus dem WindowProc-Handler für WM_SIZE Nachrichten aufgerufen wird:

    case WM_SIZE:
        if (g_pSwapChain)
        {
            g_pd3dDeviceContext->OMSetRenderTargets(0, 0, 0);

            // Release all outstanding references to the swap chain's buffers.
            g_pRenderTargetView->Release();

            HRESULT hr;
            // Preserve the existing buffer count and format.
            // Automatically choose the width and height to match the client rect for HWNDs.
            hr = g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
                                            
            // Perform error handling here!

            // Get buffer and create a render-target-view.
            ID3D11Texture2D* pBuffer;
            hr = g_pSwapChain->GetBuffer(0, __uuidof( ID3D11Texture2D),
                                         (void**) &pBuffer );
            // Perform error handling here!

            hr = g_pd3dDevice->CreateRenderTargetView(pBuffer, NULL,
                                                     &g_pRenderTargetView);
            // Perform error handling here!
            pBuffer->Release();

            g_pd3dDeviceContext->OMSetRenderTargets(1, &g_pRenderTargetView, NULL );

            // Set up the viewport.
            D3D11_VIEWPORT vp;
            vp.Width = width;
            vp.Height = height;
            vp.MinDepth = 0.0f;
            vp.MaxDepth = 1.0f;
            vp.TopLeftX = 0;
            vp.TopLeftY = 0;
            g_pd3dDeviceContext->RSSetViewports( 1, &vp );
        }
        return 1;

Auswählen der DXGI-Ausgabe und -Größe

Standardmäßig wählt DXGI die Ausgabe aus, die den größten Teil des Clientbereichs des Fensters enthält. Dies ist die einzige Option, die DXGI zur Verfügung stellt, wenn sie als Reaktion auf die Alt-Eingabe selbst in den Vollbildmodus wechselt. Wenn die Anwendung sich dafür entscheidet, selbst in den Vollbildmodus zu wechseln, kann sie IDXGISwapChain::SetFullscreenState aufrufen und eine explizite IDXGIOutput1 (oder NULL übergeben, wenn die Anwendung DXGI entscheiden lässt).

Zum Ändern der Größe der Ausgabe im Vollbildmodus oder im Fenster wird empfohlen, IDXGISwapChain::ResizeTarget aufzurufen, da diese Methode auch die Größe des Zielfensters ändert. Da die Größe des Zielfensters geändert wird, sendet das Betriebssystem WM_SIZE, und Ihr Code ruft natürlich IDXGISwapChain::ResizeBuffers als Antwort auf. Es ist daher eine Verschwendung von Aufwand, die Größe Der Puffer zu ändern und anschließend die Größe des Ziels zu ändern.

Debuggen im Vollbildmodus

Eine DXGI-Swapchain gibt den Vollbildmodus nur dann auf, wenn dies unbedingt erforderlich ist. Dies bedeutet, dass Sie eine Vollbildanwendung mit mehreren Monitoren debuggen können, solange das Debugfenster das Zielfenster der Swapchain nicht überschneidet. Alternativ können Sie den Moduswechsel ganz verhindern, indem Sie das DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH-Flag nicht festlegen.

Wenn der Moduswechsel zulässig ist, gibt eine Swapchain den Vollbildmodus auf, wenn das Ausgabefenster von einem anderen Fenster verdeckt wird. Die Okclusionsprüfung wird während IDXGISwapChain1::P resent1 oder durch einen separaten Thread durchgeführt, dessen Zweck darin besteht, watch zu überprüfen, ob die Anwendung nicht mehr reagiert (und IDXGISwapChain1::P resent1 nicht mehr aufruft). Um die Möglichkeit des separaten Threads zu deaktivieren, einen Schalter zu verursachen, legen Sie den folgenden Registrierungsschlüssel auf einen beliebigen Wert ungleich 0 fest.

HKCU\Software\Microsoft\DXGI\DisableFullscreenWatchdog

Zerstören einer Swapchain

Sie dürfen eine Swapchain nicht im Vollbildmodus freigeben, da dadurch Threadkonflikte entstehen können (was dazu führt, dass DXGI eine nicht fortsetzbare Ausnahme auslöst). Bevor Sie eine Swapchain freigeben, wechseln Sie zunächst in den Fenstermodus (mit IDXGISwapChain::SetFullscreenState( FALSE, NULL )), und rufen Sie dann IUnknown::Release auf.

Verwenden eines gedrehten Monitors

Eine Anwendung muss sich keine Gedanken über die Ausrichtung des Monitors machen. DXGI rotiert bei Bedarf einen Swap-Chain-Puffer während der Präsentation. Natürlich kann sich diese zusätzliche Drehung auf die Leistung auswirken. Um eine optimale Leistung zu erzielen, sorgen Sie für die Rotation in Ihrer Anwendung, indem Sie die folgenden Schritte ausführen:

  • Verwenden Sie die DXGI_SWAP_CHAIN_FLAG_NONPREROTATED. Dadurch wird DXGI benachrichtigt, dass die Anwendung ein gedrehtes Bild erzeugt (z. B. durch Ändern der Projektionsmatrix). Beachten Sie, dass dieses Flag nur im Vollbildmodus gültig ist.
  • Ordnen Sie jeden Swapchainpuffer in seiner gedrehten Größe zu. Verwenden Sie IDXGIOutput::GetDesc , um diese Werte bei Bedarf abzurufen.

Wenn Sie die Drehung in Ihrer Anwendung ausführen, führt DXGI einfach eine Kopie anstelle einer Kopie und einer Drehung durch.

Die Direct3D 11.1-Runtime, die ab Windows 8 verfügbar ist, bietet eine Flip-Modell-Swapchain (d. h. eine Swap chain, für die der DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL Wert im SwapEffect-Membervon DXGI_SWAP_CHAIN_DESC1 festgelegt ist). Um die mit einer Flip-Model-Swapchain verfügbaren Präsentationsoptimierungen zu maximieren, wird empfohlen, dass Ihre Anwendungen den Inhalt so ausrichten, dass sie an der bestimmten Ausgabe, in der sich der Inhalt befindet, angibt, wenn dieser Inhalt die Ausgabe vollständig belegt. Weitere Informationen zu Flipmodell-Swapchains und ihren Vorteilen finden Sie unter DXGI Flip Model.

Wechseln von Modi

Die DXGI-Swapkette kann den Anzeigemodus einer Ausgabe ändern, wenn ein Vollbildübergang erfolgt. Um die Änderung des automatischen Anzeigemodus zu aktivieren, müssen Sie in der Swap-Chain-Beschreibung DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH angeben. Wenn sich der Anzeigemodus automatisch ändert, wählt DXGI den bescheidensten Modus (Größe und Auflösung ändern sich nicht, die Farbtiefe kann jedoch nicht geändert werden). Das Ändern der Größe von Swap chain-Puffern führt nicht zu einem Moduswechsel. Die Swapchain gibt eine implizite Zusage: Wenn Sie einen Rückpuffer auswählen, der genau einem anzeigemodus entspricht, der von der Zielausgabe unterstützt wird, wechselt er in diesen Anzeigemodus, wenn er in dieser Ausgabe in den Vollbildmodus wechselt. Daher wählen Sie einen Anzeigemodus aus, indem Sie die Größe und das Format Ihres Backpuffers auswählen.

Tipp für die Vollbildleistung

Wenn Sie IDXGISwapChain1::P resent1 in einer Vollbildanwendung aufrufen, kippt die Swapchain (im Gegensatz zu blits) den Inhalt des Backpuffers auf den vorderen Puffer. Dies erfordert, dass die Swapchain mithilfe eines aufgezählten Anzeigemodus (in DXGI_SWAP_CHAIN_DESC1 angegeben) erstellt wurde. Wenn Sie anzeigemodi nicht aufzählen oder den Anzeigemodus in der Beschreibung fälschlicherweise angeben, führt die Swapchain möglicherweise stattdessen eine Bitblockübertragung (Bitblt) durch. Die Bitblt verursacht eine zusätzliche Dehnungskopie sowie eine erhöhte Videospeicherauslastung und ist schwer zu erkennen. Um dieses Problem zu vermeiden, führen Sie anzeigemodi auf, und initialisieren Sie die Swapchainbeschreibung richtig, bevor Sie die Swapchain erstellen. Dadurch wird maximale Leistung beim Drehen im Vollbildmodus sichergestellt und der zusätzliche Arbeitsspeicheraufwand vermieden.

Überlegungen zu Multithreads

Wenn Sie DXGI in einer Anwendung mit mehreren Threads verwenden, müssen Sie darauf achten, dass kein Deadlock erstellt wird, bei dem zwei verschiedene Threads aufeinander warten, bis sie abgeschlossen werden. Es gibt zwei Situationen, in denen dies auftreten kann.

  • Der Renderingthread ist nicht der Nachrichtenpumpthread.
  • Der Thread, der eine DXGI-API ausführt, ist nicht derselbe Thread, der das Fenster erstellt hat.

Achten Sie darauf, dass der Nachrichtenpumpthread nie auf den Renderthread wartet, wenn Sie Vollbild-Swapchains verwenden. Für instance kann der Aufruf von IDXGISwapChain1::P resent1 (aus dem Renderthread) dazu führen, dass der Renderthread auf den Nachrichtenpumpenthread wartet. Wenn eine Modusänderung auftritt, ist dieses Szenario möglich, wenn Present1 ::SetWindowPos() oder ::SetWindowStyle() aufruft und eine dieser Methoden ::SendMessage() aufruft. Wenn der Nachrichtenpumpthread in diesem Szenario über einen kritischen Abschnitt verfügt, der ihn schützt, oder wenn der Renderthread blockiert wird, werden die beiden Threads deadlockt.

Weitere Informationen zur Verwendung von DXGI mit mehreren Threads finden Sie unter Multithreading und DXGI.

DXGI-Antworten von DLLMain

Da eine DllMain-Funktion nicht garantieren kann, in welcher Reihenfolge DLLs geladen und entladen werden, wird empfohlen, dass die DllMain-Funktion Ihrer App keine Direct3D- oder DXGI-Funktionen oder -Methoden aufruft, einschließlich Funktionen oder Methoden, die Objekte erstellen oder freigeben. Wenn die DllMain-Funktion Ihrer App eine bestimmte Komponente aufruft, ruft diese Komponente möglicherweise eine andere DLL auf, die auf dem Betriebssystem nicht vorhanden ist, was zu einem Absturz des Betriebssystems führt. Direct3D und DXGI laden möglicherweise eine Reihe von DLLs, in der Regel eine Reihe von Treibern, die sich von Computer zu Computer unterscheiden. Selbst wenn Ihre App nicht auf Ihren Entwicklungs- und Testcomputern abstürzt, wenn die DllMain-Funktion Direct3D- oder DXGI-Funktionen oder -Methoden aufruft, kann sie daher abstürzen, wenn sie auf einem anderen Computer ausgeführt wird.

Um zu verhindern, dass Sie eine App erstellen, die zu einem Absturz des Betriebssystems führen kann, stellt DXGI in den angegebenen Situationen die folgenden Antworten bereit:

  • Wenn die DllMain-Funktion Ihrer App den letzten Verweis auf eine DXGI-Factory freigibt, löst DXGI eine Ausnahme aus.
  • Wenn die DllMain-Funktion Ihrer App eine DXGI-Factory erstellt, gibt DXGI einen Fehlercode zurück.

Änderungen an DXGI 1.1

Wir haben die folgenden Funktionen in DXGI 1.1 hinzugefügt.

Änderungen an DXGI 1.2

Wir haben die folgenden Funktionen in DXGI 1.2 hinzugefügt.

  • Stereo-Swapchain
  • Flip-Modell-Swapchain
  • Optimierte Präsentation (Bildlauf, modifiziert Rechtecke und Drehung)
  • Verbesserte freigegebene Ressourcen und Synchronisierung
  • Desktopduplizierung
  • Optimierte Nutzung des Videospeichers
  • Unterstützung für bpp-Formate (16 Bit pro Pixel) (DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM)
  • Debuggen von APIs

Weitere Informationen zu DXGI 1.2 finden Sie unter DXGI 1.2-Verbesserungen.

Programmierhandbuch für DXGI