Verarbeiten von Gerät entfernt-Szenarien in Direct3D 11Handle device removed scenarios in Direct3D 11

In diesem Thema wird erläutert, wie Sie die Geräteschnittstellenkette für Direct3D und DXGI neu erstellen, wenn die Grafikkarte entfernt oder neu initialisiert wird.This topic explains how to recreate the Direct3D and DXGI device interface chain when the graphics adapter is removed or reinitialized.

In DirectX 9 kann für Anwendungen die Bedingung "Gerät ist nicht mehr auffindbar" entstehen, bei der das D3D-Gerät nicht mehr betriebsbereit ist.In DirectX 9, applications could encounter a "device lost" condition where the D3D device enters a non-operational state. Wenn eine Direct3D 9-Vollbildanwendung den Fokus verliert, ist das Direct3D-Gerät „nicht mehr auffindbar“. Alle Versuche, mit einem nicht auffindbaren Gerät zu zeichnen, sind nicht erfolgreich (ohne Warnung).For example, when a full-screen Direct3D 9 application loses focus, the Direct3D device becomes "lost;" any attempts to draw with a lost device will silently fail. Für Direct3D 11 werden virtuelle Grafikgerätschnittstellen verwendet, damit mehrere Programme dasselbe physische Grafikgerät nutzen können und keine Bedingungen entstehen, in denen Apps die Kontrolle über das Direct3D-Gerät verlieren.Direct3D 11 uses virtual graphics device interfaces, enabling multiple programs to share the same physical graphics device and eliminating conditions where apps lose control of the Direct3D device. Es ist jedoch weiterhin möglich, dass sich die Verfügbarkeit der Grafikkarte ändert.However, it is still possible for graphics adapter availability to change. Zum Beispiel:For example:

  • Der Grafiktreiber wird aktualisiert.The graphics driver is upgraded.
  • Das System führt eine Umstellung von einer energiesparenden Grafikkarte auf eine Grafikkarte mit hoher Leistung durch.The system changes from a power-saving graphics adapter to a performance graphics adapter.
  • Das Grafikgerät reagiert nicht mehr und wird zurückgesetzt.The graphics device stops responding and is reset.
  • Eine Grafikkarte wird physisch angeschlossen oder entfernt.A graphics adapter is physically attached or removed.

Unter diesen Umständen wird von DXGI ein Fehlercode zurückgegeben, der angibt, dass das Direct3D-Gerät neu initialisiert werden muss und die Geräteressourcen neu erstellt werden müssen.When such circumstances arise, DXGI returns an error code indicating that the Direct3D device must be reinitialized and device resources must be recreated. In dieser exemplarischen Vorgehensweise wird erläutert, wie Direct3D 11-Apps und -Spiele Fälle, in denen die Grafikkarte zurückgesetzt, entfernt oder geändert wird, erkennen und darauf reagieren kann.This walkthrough explains how Direct3D 11 apps and games can detect and respond to any circumstance where the graphics adapter is reset, removed, or changed. Codebeispiele werden über die DirectX 11-App (Universelles Windows)-Vorlage, die mit Microsoft Visual Studio 2015 bereitgestellten bereitgestellt.Code examples are provided from the DirectX 11 App (Universal Windows) template provided with Microsoft Visual Studio 2015.

AnweisungenInstructions

Schritt 1:Step 1:

Fügen Sie eine Überprüfung auf den Fehler „Gerät entfernt“ in die Renderschleife ein.Include a check for the device removed error in the rendering loop. Stellen Sie den Frame dar, indem Sie IDXGISwapChain::Present (bzw. Present1 usw.) aufrufen.Present the frame by calling IDXGISwapChain::Present (or Present1, and so on). Klicken Sie dann überprüfen, ob sie zurückgegeben DXGI_Fehler_Gerät_entfernt oder DXGI_Fehler_Gerät _Zurücksetzen.Then, check whether it returned DXGI_ERROR_DEVICE_REMOVED or DXGI_ERROR_DEVICE_RESET.

Zuerst wird in der Vorlage der HRESULT-Wert gespeichert, der von der DXGI-Swapchain zurückgegeben wird:First, the template stores the HRESULT returned by the DXGI swap chain:

HRESULT hr = m_swapChain->Present(1, 0);

Nachdem Sie alle anderen Schritte zum Darstellen des Frames ausgeführt haben, führt die Vorlage eine Überprüfung auf den Fehler aufgrund eines entfernten Geräts durch.After taking care of all other work for presenting the frame, the template checks for the device removed error. Bei Bedarf wird eine Methode zum Behandeln der Bedingung „Gerät entfernt“ aufgerufen:If necessary, it calls a method to handle the device removed condition:

// If the device was removed either by a disconnection or a driver upgrade, we
// must recreate all device resources.
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
    HandleDeviceLost();
}
else
{
    DX::ThrowIfFailed(hr);
}

Schritt 2:Step 2:

Fügen Sie auch eine Überprüfung auf den Fehler „Gerät entfernt“ ein, wenn Sie auf Änderungen der Fenstergröße reagieren.Also, include a check for the device removed error when responding to window size changes. Dies ist ein guter Ausgangspunkt zu prüfen, DXGI_Fehler_Gerät_entfernt oder DXGI_Fehler_Gerät_ Zurücksetzen verschiedene Ursachen haben:This is a good place to check for DXGI_ERROR_DEVICE_REMOVED or DXGI_ERROR_DEVICE_RESET for several reasons:

  • Das Ändern der Größe der Swapchain erfordert das Aufrufen des zugrunde liegenden DXGI-Adapters, von dem der Fehler „Gerät entfernt“ zurückgegeben werden kann.Resizing the swap chain requires a call to the underlying DXGI adapter, which can return the device removed error.
  • Möglicherweise wurde die App auf einen Monitor verschoben, der an ein anderes Grafikgerät angeschlossen ist.The app might have moved to a monitor that's attached to a different graphics device.
  • Wenn ein Grafikgerät entfernt oder zurückgesetzt wird, ändert sich häufig die Desktopauflösung. Dies führt zu einer Änderung der Fenstergröße.When a graphics device is removed or reset, the desktop resolution often changes, resulting in a window size change.

Die Vorlage überprüft den HRESULT-Wert, der von ResizeBuffers zurückgegeben wird:The template checks the HRESULT returned by ResizeBuffers:

// If the swap chain already exists, resize it.
HRESULT hr = m_swapChain->ResizeBuffers(
    2, // Double-buffered swap chain.
    static_cast<UINT>(m_d3dRenderTargetSize.Width),
    static_cast<UINT>(m_d3dRenderTargetSize.Height),
    DXGI_FORMAT_B8G8R8A8_UNORM,
    0
    );

if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
    // If the device was removed for any reason, a new device and swap chain will need to be created.
    HandleDeviceLost();

    // Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method 
    // and correctly set up the new device.
    return;
}
else
{
    DX::ThrowIfFailed(hr);
}

Schritt 3:Step 3:

Jedes Mal, die Ihre app empfängt die DXGI_Fehler_Gerät_entfernt Fehler muss alle geräteabhängigen neu zu erstellen und initialisieren Sie das Direct3D-Gerät erneut Ressourcen zu.Any time your app receives the DXGI_ERROR_DEVICE_REMOVED error, it must reinitialize the Direct3D device and recreate any device-dependent resources. Geben Sie alle Verweise auf Ressourcen des Grafikgeräts frei, die mit dem vorherigen Direct3D-Gerät erstellt wurden. Diese Ressourcen sind jetzt ungültig, und alle Verweise auf die Swapchain müssen freigegeben werden, bevor eine neue erstellt werden kann.Release any references to graphics device resources created with the previous Direct3D device; those resources are now invalid, and all references to the swap chain must be released before a new one can be created.

Die HandleDeviceLost-Methode gibt die Swapchain frei und weist die App-Komponenten an, die Geräteressourcen freizugeben:The HandleDeviceLost method releases the swap chain and notifies app components to release device resources:

m_swapChain = nullptr;

if (m_deviceNotify != nullptr)
{
    // Notify the renderers that device resources need to be released.
    // This ensures all references to the existing swap chain are released so that a new one can be created.
    m_deviceNotify->OnDeviceLost();
}

Anschließend erstellt sie eine neue Swapchain und initialisiert die geräteabhängigen Ressourcen neu, die von der Geräteverwaltungsklasse gesteuert werden:Then, it creates a new swap chain and reinitializes the device-dependent resources controlled by the device management class:

// Create the new device and swap chain.
CreateDeviceResources();
m_d2dContext->SetDpi(m_dpi, m_dpi);
CreateWindowSizeDependentResources();

Nachdem das Gerät und die Swapchain neu eingerichtet wurden, werden die App-Komponenten angewiesen, geräteabhängige Ressourcen neu zu initialisieren:After the device and swap chain have been re-established, it notifies app components to reinitialize device-dependent resources:

// Create the new device and swap chain.
CreateDeviceResources();
m_d2dContext->SetDpi(m_dpi, m_dpi);
CreateWindowSizeDependentResources();

if (m_deviceNotify != nullptr)
{
    // Notify the renderers that resources can now be created again.
    m_deviceNotify->OnDeviceRestored();
}

Wenn die HandleDeviceLost-Methode beendet wird, geht die Steuerung wieder auf die Renderschleife über, die dann mit dem Zeichnen des nächsten Frames fortfährt.When the HandleDeviceLost method exits, control returns to the rendering loop, which continues on to draw the next frame.

HinweiseRemarks

Untersuchen der Ursache für Fehler vom Typ „Gerät entfernt“Investigating the cause of device removed errors

Wiederkehrende Probleme mit dem DXGI-Fehler „Gerät entfernt“ können darauf hinweisen, dass von Ihrem Grafikcode während einer Zeichenroutine ungültige Bedingungen erstellt werden.Repeat issues with DXGI device removed errors can indicate that your graphics code is creating invalid conditions during a drawing routine. Außerdem können sie auf einen Hardwarefehler oder einen Fehler in der Grafikkarte hinweisen.It can also indicate a hardware failure or a bug in the graphics driver. Rufen Sie zum Untersuchen der Fehler vom Typ „Gerät entfernt“ ID3D11Device::GetDeviceRemovedReason auf, bevor Sie das Direct3D-Gerät freigeben.To investigate the cause of device removed errors, call ID3D11Device::GetDeviceRemovedReason before releasing the Direct3D device. Diese Methode gibt einen von sechs möglichen DXGI-Fehlercodes zurück, um die Ursache des Fehlers „Gerät entfernt“ anzugeben:This method returns one of six possible DXGI error codes indicating the reason for the device removed error:

  • DXGI_FEHLER_GERÄT_ABGESTÜRZTER: Der Grafiktreiber reagiert aufgrund eine ungültige Kombination von Grafikbefehle, die von der app gesendet.DXGI_ERROR_DEVICE_HUNG: The graphics driver stopped responding because of an invalid combination of graphics commands sent by the app. Wenn Sie diesen Fehler häufiger erhalten, ist dies ein Hinweis darauf, dass Ihre App zum Hängen des Geräts geführt hat und ein Debugvorgang durchgeführt werden muss.If you get this error repeatedly, it is a likely indication that your app caused the device to hang and needs to be debugged.
  • DXGI_FEHLER_GERÄT_ENTFERNT: Das Grafikgerät physisch entfernt wurde, deaktiviert ist, oder ein treiberupgrade ist aufgetreten.DXGI_ERROR_DEVICE_REMOVED: The graphics device has been physically removed, turned off, or a driver upgrade has occurred. Dies geschieht von Zeit zu Zeit und ist normal. Die App bzw. das Spiel sollte die Geräteressourcen wie in diesem Thema beschrieben neu erstellen.This happens occasionally and is normal; your app or game should recreate device resources as described in this topic.
  • DXGI_FEHLER_GERÄT_ZURÜCKSETZEN: Das Grafikgerät Fehler aufgrund ungültiger-Befehls.DXGI_ERROR_DEVICE_RESET: The graphics device failed because of a badly formed command. Wenn Sie diesen Fehler häufig erhalten, kann dies bedeuten, dass vom Code ungültige Zeichenbefehle gesendet werden.If you get this error repeatedly, it may mean that your code is sending invalid drawing commands.
  • DXGI_FEHLER_TREIBER_INTERN_FEHLER: Der Grafiktreiber ist ein Fehler aufgetreten, und das Gerät zurückgesetzt.DXGI_ERROR_DRIVER_INTERNAL_ERROR: The graphics driver encountered an error and reset the device.
  • DXGI_FEHLER_UNGÜLTIGE_AUFRUFEN: Die Anwendung bereitgestellte Daten für ungültige Parameter.DXGI_ERROR_INVALID_CALL: The application provided invalid parameter data. Auch wenn Sie diesen Fehler nur einmal erhalten, bedeutet dies, dass Ihr Code die Bedingung „Gerät entfernt“ verursacht hat und ein Debugvorgang durchgeführt werden muss.If you get this error even once, it means that your code caused the device removed condition and must be debugged.
  • S_OK: Zurückgegeben, wenn ein Grafikgerät wurde aktiviert, deaktiviert oder zurücksetzen, ohne die aktuellen-Grafikgerät für ungültig zu erklären.S_OK: Returned when a graphics device was enabled, disabled, or reset without invalidating the current graphics device. Dieser Fehler kann beispielsweise zurückgegeben werden, wenn eine App die Windows Advanced Rasterization Platform (WARP) verwendet und ein Hardwareadapter verfügbar wird.For example, this error code can be returned if an app is using Windows Advanced Rasterization Platform (WARP) and a hardware adapter becomes available.

Der folgende Code Ruft die DXGI_Fehler_Gerät_entfernt Fehler code, und klicken Sie in der Debugging-Konsole ausgeben.The following code will retrieve the DXGI_ERROR_DEVICE_REMOVED error code and print it to the debug console. Fügen Sie diesen Code am Anfang der HandleDeviceLost-Methode hinzu:Insert this code at the beginning of the HandleDeviceLost method:

    HRESULT reason = m_d3dDevice->GetDeviceRemovedReason();

#if defined(_DEBUG)
    wchar_t outString[100];
    size_t size = 100;
    swprintf_s(outString, size, L"Device removed! DXGI_ERROR code: 0x%X\n", reason);
    OutputDebugStringW(outString);
#endif

Weitere Informationen finden Sie unter GetDeviceRemovedReason und DXGI_Fehler.For more details, see GetDeviceRemovedReason and DXGI_ERROR.

Testgerät hat Behandlung entferntTesting Device Removed Handling

Die Developer-Eingabeaufforderung für Visual Studio unterstützt das Befehlszeilenprogramm „dxcap“ für die Direct3D-Ereigniserfassung und -Wiedergabe im Zusammenhang mit der Visual Studio-Grafikdiagnose.Visual Studio's Developer Command Prompt supports a command line tool 'dxcap' for Direct3D event capture and playback related to the Visual Studio Graphics Diagnostics. Können Sie die Befehlszeilenoption folgender Option "-Forcetdr" während Ihrer app die zwingt, ein GPU-Timeouterkennungs- und Wiederherstellungsfunktion-Ereignis ausgeführt wird, wodurch auslösen DXGI_Fehler_Gerät_entfernt und dadurch können Sie den Fehler zu testen. Verarbeitung von Code.You can use the command line option "-forcetdr" while your app is running which will force a GPU Timeout Detection and Recovery event, thereby triggering DXGI_ERROR_DEVICE_REMOVED and allowing you to test your error handling code.

Hinweis DXCap und die Unterstützungs-DLLs werden unter „system32/syswow64“ als Teil der Grafiktools für Windows 10 installiert, die nicht mehr über das Windows SDK verteilt werden.Note DXCap and its support DLLs are installed into system32/syswow64 as part of the Graphics Tools for Windows 10 which are no longer distributed via the Windows SDK. Stattdessen werden sie über das bei Bedarf verfügbare Feature „Grafiktools“ bereitgestellt. Dies ist eine optionale Betriebssystemkomponente, die installiert sein muss, um die Grafiktools unter Windows 10 zu aktivieren und zu verwenden.Instead they are provided via the Graphics Tools Feature on Demand that is an optional OS component and must be installed in order to enable and use the Graphics Tools on Windows 10. Weitere Informationen zum Installieren der Grafiktools für Windows 10 finden Sie hier: https://msdn.microsoft.com/library/mt125501.aspx#InstallGraphicsToolsMore information on how to Install the Graphics Tools for Windows 10 can be found here: https://msdn.microsoft.com/library/mt125501.aspx#InstallGraphicsTools