Gérer des scénarios de suppression d’appareils dans Direct3D 11Handle device removed scenarios in Direct3D 11

Cette rubrique explique comment recréer la chaîne d’interface d’appareils Direct3D et DXGI quand la carte graphique est supprimée ou réinitialisée.This topic explains how to recreate the Direct3D and DXGI device interface chain when the graphics adapter is removed or reinitialized.

Dans DirectX 9, les applications peuvent présenter un état de type « périphérique perdu » quand un périphérique D3D passe à un état non opérationnel.In DirectX 9, applications could encounter a "device lost" condition where the D3D device enters a non-operational state. Par exemple, lorsqu’une application Direct3D 9 en mode plein écran perd le focus, le périphérique Direct3D est « perdu ». Toute tentative de dessin avec un périphérique perdu entraîne un échec sans avertissement.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. Direct3D 11 utilise des interfaces GDI (Graphics Device Interface) virtuelles, ce qui permet à plusieurs programmes de partager le même périphérique graphique physique et d’éviter les situations où les applications perdent le contrôle du périphérique Direct3D.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. Cependant, la disponibilité de la carte graphique peut toujours changer.However, it is still possible for graphics adapter availability to change. Par exemple :For example:

  • Le pilote graphique est mis à jour.The graphics driver is upgraded.
  • Le système passe d’une carte graphique axée sur l’économie d’énergie à une carte graphique axée sur les performances.The system changes from a power-saving graphics adapter to a performance graphics adapter.
  • Le périphérique graphique cesse de répondre et est réinitialisé.The graphics device stops responding and is reset.
  • Une carte graphique est attachée ou supprimée physiquement.A graphics adapter is physically attached or removed.

Dans ces circonstances, DXGI retourne un code d’erreur indiquant que le périphérique Direct3D doit être réinitialisé et que les ressources de périphérique doivent être recréées.When such circumstances arise, DXGI returns an error code indicating that the Direct3D device must be reinitialized and device resources must be recreated. Cette procédure pas à pas montre comment les applications et les jeux Direct3D 11 peuvent détecter ces situations et réagir de manière appropriée quand la carte graphique est réinitialisée, supprimée ou modifiée.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. Des exemples de code sont fournis à partir des modèles d’applications DirectX 11 (Windows universelles) inclus dans Microsoft Visual Studio 2015.Code examples are provided from the DirectX 11 App (Universal Windows) template provided with Microsoft Visual Studio 2015.

InstructionsInstructions

Étape 1 :Step 1:

Incluez une recherche de l’erreur relative à une suppression d’appareil dans la boucle de rendu.Include a check for the device removed error in the rendering loop. Présentez le frame en appelant IDXGISwapChain ::P renvoyée (ou Present1, etc.).Present the frame by calling IDXGISwapChain::Present (or Present1, and so on). Vérifiez ensuite s’il a retourné dxgi _ erreur de _ périphérique _ supprimé ou la ** _ _ _ réinitialisation du périphérique d’erreur dxgi**.Then, check whether it returned DXGI_ERROR_DEVICE_REMOVED or DXGI_ERROR_DEVICE_RESET.

Tout d’abord, le modèle stocke le HRESULT retourné par la chaîne de permutation DXGI :First, the template stores the HRESULT returned by the DXGI swap chain:

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

Après avoir géré les autres travaux de présentation de l’image, le modèle vérifie s’il existe une erreur relative à la suppression de périphérique.After taking care of all other work for presenting the frame, the template checks for the device removed error. Si nécessaire, il appelle une méthode pour gérer l’état de suppression du périphérique :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);
}

Étape 2 :Step 2:

Incluez également une recherche de l’erreur relative à une suppression de périphérique en réponse aux changements de taille de fenêtre.Also, include a check for the device removed error when responding to window size changes. Il s’agit d’un bon emplacement pour vérifier la suppression de l' ** _ appareil d’erreur _ _ dxgi** ou la ** _ _ _ réinitialisation de l’appareil dxgi** pour plusieurs raisons :This is a good place to check for DXGI_ERROR_DEVICE_REMOVED or DXGI_ERROR_DEVICE_RESET for several reasons:

  • Le redimensionnement de la chaîne de permutation nécessite un appel à l’adaptateur DXGI sous-jacent, ce qui peut retourner l’erreur relative à une suppression de périphérique.Resizing the swap chain requires a call to the underlying DXGI adapter, which can return the device removed error.
  • L’application peut avoir été déplacée vers un moniteur attaché à un autre périphérique graphique.The app might have moved to a monitor that's attached to a different graphics device.
  • Quand un appareil graphique est supprimé ou réinitialisé, la résolution du Bureau change le plus souvent, ce qui entraîne un changement de taille de fenêtre.When a graphics device is removed or reset, the desktop resolution often changes, resulting in a window size change.

Le modèle vérifie le HRESULT retourné par ResizeBuffers: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);
}

Étape 3 :Step 3:

Chaque fois que votre application reçoit l’erreur dxgi _ erreur de _ _ suppression de l’appareil, elle doit réinitialiser l’appareil Direct3D et recréer toutes les ressources dépendantes de l’appareil.Any time your app receives the DXGI_ERROR_DEVICE_REMOVED error, it must reinitialize the Direct3D device and recreate any device-dependent resources. Libérez les références aux ressources d’appareil graphique créées avec le précédent appareil Direct3D. Ces ressources ne sont plus valides. Toutes les références à la chaîne de permutation doivent être libérées pour en permettre la création d’une autre.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.

La méthode HandleDeviceLost libère la chaîne d’échange et indique aux composants d’application de libérer les ressources de périphérique :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();
}

Elle crée ensuite une chaîne d’échange, puis réinitialise les ressources dépendantes du périphérique contrôlées par la classe de gestion de périphérique :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();

Une fois que le périphérique et la chaîne d’échange ont été rétablis, la méthode indique aux composants d’application de réinitialiser les ressources dépendantes du périphérique :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();
}

À la fin de la méthode HandleDeviceLost, le contrôle retourne à la boucle de rendu, qui continue de dessiner l’image suivante.When the HandleDeviceLost method exits, control returns to the rendering loop, which continues on to draw the next frame.

RemarquesRemarks

Recherche de l’origine des erreurs relatives à une suppression de périphériqueInvestigating the cause of device removed errors

La répétition d’erreurs relatives à une suppression de périphérique DXGI peut indiquer que votre code graphique crée des conditions non valides durant une routine de dessin.Repeat issues with DXGI device removed errors can indicate that your graphics code is creating invalid conditions during a drawing routine. Elle peut également indiquer une défaillance matérielle ou un bogue dans le pilote graphique.It can also indicate a hardware failure or a bug in the graphics driver. Pour rechercher l’origine des erreurs relatives à une suppression de périphérique, appelez ID3D11Device::GetDeviceRemovedReason avant de libérer le périphérique Direct3D.To investigate the cause of device removed errors, call ID3D11Device::GetDeviceRemovedReason before releasing the Direct3D device. Cette méthode retourne l’un des six codes d’erreur DXGI possibles qui indiquent l’origine de l’erreur relative à une suppression de périphérique :This method returns one of six possible DXGI error codes indicating the reason for the device removed error:

  • Dxgi _ Périphérique d’erreur _ _ bloqué: le pilote Graphics a cessé de répondre en raison d’une combinaison non valide de commandes graphiques envoyées par l’application.DXGI_ERROR_DEVICE_HUNG: The graphics driver stopped responding because of an invalid combination of graphics commands sent by the app. Si vous obtenez cette erreur à plusieurs reprises, cela indique que votre application est probablement à l’origine de la défaillance du périphérique et qu’elle doit être déboguée.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 _ Périphérique d’erreur _ _ supprimé: le périphérique graphique a été physiquement supprimé, désactivé ou une mise à niveau du pilote s’est produite.DXGI_ERROR_DEVICE_REMOVED: The graphics device has been physically removed, turned off, or a driver upgrade has occurred. Cela arrive parfois et c’est une situation normale. Votre application ou votre jeu doit recréer les ressources de périphérique, comme cela est décrit dans cette rubrique.This happens occasionally and is normal; your app or game should recreate device resources as described in this topic.
  • Dxgi _ ERREUR _ de _ réinitialisation de périphérique: le périphérique graphique a échoué en raison d’une commande incorrecte.DXGI_ERROR_DEVICE_RESET: The graphics device failed because of a badly formed command. Si vous obtenez cette erreur à plusieurs reprises, cela peut signifier que votre code envoie des commandes de dessin non valides.If you get this error repeatedly, it may mean that your code is sending invalid drawing commands.
  • Dxgi _ Erreur _ _ interne du _ pilote d’erreur: le pilote Graphics a rencontré une erreur et a réinitialisé l’appareil.DXGI_ERROR_DRIVER_INTERNAL_ERROR: The graphics driver encountered an error and reset the device.
  • Dxgi _ ERREUR _ d' _ appel non valide: l’application a fourni des données de paramètre non valides.DXGI_ERROR_INVALID_CALL: The application provided invalid parameter data. Si vous obtenez cette erreur, même une seule fois, cela signifie que votre code est à l’origine de l’état de suppression du périphérique et qu’il doit être débogué.If you get this error even once, it means that your code caused the device removed condition and must be debugged.
  • S _ OK: retourné lorsqu’un périphérique graphique a été activé, désactivé ou réinitialisé sans invalider le périphérique graphique actuel.S_OK: Returned when a graphics device was enabled, disabled, or reset without invalidating the current graphics device. Par exemple, ce code d’erreur peut être retourné si une application utilise WARP (Windows Advanced Rasterization Platform) et si un adaptateur matériel est disponible.For example, this error code can be returned if an app is using Windows Advanced Rasterization Platform (WARP) and a hardware adapter becomes available.

Le code suivant récupère le code d’erreur dxgi _ Error _ Device _ supprimé et l’imprime dans la console de débogage.The following code will retrieve the DXGI_ERROR_DEVICE_REMOVED error code and print it to the debug console. Insérez ce code au début de la méthode HandleDeviceLost :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

Pour plus d’informations, consultez GetDeviceRemovedReason et dxgi _ Error.For more details, see GetDeviceRemovedReason and DXGI_ERROR.

Gestion de l’appareil de test suppriméTesting Device Removed Handling

L’invite de commandes de développeur de Visual Studio prend en charge un outil de ligne de commande « dxcap » pour la capture et la lecture d’événement Direct3D en rapport avec les diagnostics des graphiques Visual Studio.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. Vous pouvez utiliser l’option de ligne de commande « -forcetdr » pendant que votre application est en cours d’exécution, ce qui force un événement de détection et de récupération du délai GPU, déclenchant ainsi un _ appareil d’erreur dxgi _ _ supprimé et vous permettant de tester votre code de gestion des erreurs.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.

Remarque DXCap et ses DLL de prise en charge sont installés sur system32/syswow64 en tant qu’outils graphiques pour Windows 10, qui ne sont plus distribués via le Kit de développement logiciel (SDK) Windows.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. Ils sont désormais fournis via la fonctionnalité Outils graphiques à la demande, un composant facultatif de système d’exploitation qui doit être installé afin d’activer et d’utiliser les outils graphiques sous Windows 10.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. Vous trouverez plus d’informations sur l’installation des outils Graphics pour Windows 10 ici : 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