Direct3D 11 sur 12
D3D11On12 est un mécanisme par lequel les développeurs peuvent utiliser des interfaces et des objets D3D11 pour piloter l’API D3D12. D3D11on12 permet aux composants écrits à l’aide de D3D11 (par exemple, du texte et de l’interface utilisateur D2D) de fonctionner avec des composants écrits ciblant l’API D3D12. D3D11on12 permet également le portage incrémentiel d’une application de D3D11 vers D3D12, en permettant à certaines parties de l’application de continuer à cibler D3D11 par souci de simplicité, tandis que d’autres ciblent D3D12 pour les performances, tout en ayant toujours un rendu complet et correct. D3D11On12 simplifie l’utilisation de techniques d’interopérabilité pour partager des ressources et synchroniser le travail entre les deux API.
- Initialisation de D3D11On12
- Exemple d’utilisation
- Arrière-plan
- Nettoyage
- Limitations
- API
- Rubriques connexes
Initialisation de D3D11On12
Pour commencer à utiliser D3D11On12, la première étape consiste à créer un appareil D3D12 et une file d’attente de commandes. Ces objets sont fournis en tant qu’entrée dans la méthode d’initialisation D3D11On12CreateDevice. Vous pouvez considérer cette méthode comme la création d’un appareil D3D11 avec le type de pilote imaginaire D3D_DRIVER_TYPE_11ON12, où le pilote D3D11 est responsable de la création d’objets et de l’envoi de listes de commandes à l’API D3D12.
Une fois que vous avez un appareil D3D11 et un contexte immédiat, vous pouvez QueryInterface
désactiver l’appareil pour l’interface ID3D11On12Device . Il s’agit de l’interface principale utilisée pour l’interopérabilité entre D3D11 et D3D12. Pour que le contexte d’appareil D3D11 et les listes de commandes D3D12 fonctionnent sur les mêmes ressources, il est nécessaire de créer des « ressources encapsulées » à l’aide de l’API CreateWrappedResource . Cette méthode « promeut » une ressource D3D12 pour qu’elle soit compréhensible dans D3D11. Une ressource encapsulée démarre à l’état « acquis », propriété qui est manipulée par les méthodes AcquireWrappedResources et ReleaseWrappedResources .
Exemple d’utilisation
L’utilisation classique de D3D11On12 serait d’utiliser D2D pour afficher du texte ou des images sur une mémoire tampon D3D12. Consultez l’exemple D3D11On12 pour obtenir un exemple de code. Voici un aperçu des étapes à suivre pour ce faire :
- Créez un appareil D3D12 (D3D12CreateDevice) et une chaîne d’échange D3D12 (CreateSwapChain avec un ID3D12CommandQueue comme entrée).
- Créez un appareil D3D11On12 à l’aide de l’appareil D3D12 et de la même file d’attente de commandes que l’entrée.
- Récupérez les mémoires tampons d’arrière de la chaîne d’échange et créez des ressources encapsulées D3D11 pour chacune d’elles. L’état d’entrée utilisé doit être la dernière façon dont D3D12 l’a utilisé (par exemple, RENDER_TARGET) et l’état de sortie doit être la façon dont D3D12 l’utilisera une fois D3D11 terminé (par exemple, PRESENT).
- Initialisez D2D et fournissez les ressources encapsulées D3D11 à D2D pour préparer le rendu.
Ensuite, sur chaque image, procédez comme suit :
- Effectuez un rendu dans la mémoire tampon d’arrière de la chaîne d’échange actuelle à l’aide d’une liste de commandes D3D12, puis exécutez-le.
- Acquérir la ressource encapsulée de la mémoire tampon arrière actuelle (AcquireWrappedResources).
- Émettez des commandes de rendu D2D.
- Relâchez la ressource encapsulée (ReleaseWrappedResources).
- Videz le contexte immédiat D3D11.
- Présent (IDXGISwapChain1::P resent1).
Arrière-plan
D3D11On12 fonctionne systématiquement. Chaque appel d’API D3D11 passe par la validation d’exécution classique et accède au pilote. Au niveau de la couche pilote, le pilote 11on12 spécial enregistre l’état et les problèmes de rendu des opérations dans les listes de commandes D3D12. Ces listes de commandes sont envoyées en fonction des besoins (par exemple, une requête GetData
ou une ressource Map
peut nécessiter une vidage des commandes) ou comme demandé par Flush. La création d’un objet D3D11 entraîne généralement la création de l’objet D3D12 correspondant. Certaines opérations de rendu de fonction fixe dans D3D11, telles que GenerateMips
ou DrawAuto
ne sont pas prises en charge dans D3D12, D3D11On12 les émule à l’aide de nuanceurs et de ressources supplémentaires.
Pour l’interopérabilité, il est important de comprendre comment D3D11On12 interagit avec les objets D3D12 que l’application a créés et fournis. Pour garantir que le travail se produit dans l’ordre correct, le contexte immédiat D3D11 doit être vidé avant que des travaux D3D12 supplémentaires puissent être envoyés à cette file d’attente. Il est également important de s’assurer que la file d’attente donnée à D3D11On12 doit être drainable à tout moment. Cela signifie que toutes les attentes sur la file d’attente doivent finalement être satisfaites, même si le thread de rendu D3D11 bloque indéfiniment. Veillez à ne pas dépendre du moment où D3D11On12 insère des vidages ou attend, car cela peut changer avec les versions ultérieures. En outre, D3D11On12 suit et manipule les états des ressources par lui-même. La seule façon de garantir la cohérence des transitions d’état consiste à utiliser les API d’acquisition/mise en production pour manipuler le suivi d’état en fonction des besoins de l’application.
Nettoyage
Pour libérer une ressource encapsulée D3D11On12, deux choses doivent se produire dans cet ordre :
- Toutes les références à la ressource, y compris toutes les vues de la ressource, doivent être publiées.
- Le traitement de la destruction différée doit avoir lieu. Le moyen le plus simple de s’assurer que cela se produit consiste à appeler l’API de contexte
Flush
immédiat.
Une fois ces deux étapes terminées, toutes les références effectuées par la ressource encapsulée doivent être publiées, et la ressource D3D12 devient exclusivement détenue par le composant D3D12. N’oubliez pas que D3D12 nécessite toujours d’attendre l’achèvement du GPU avant de libérer complètement une ressource. Veillez donc à conserver une référence sur la ressource avant d’effectuer les deux étapes ci-dessus, sauf si vous avez déjà confirmé que le GPU n’utilise plus la ressource.
Toutes les autres ressources ou objets créés par D3D11On12 seront nettoyés au moment opportun, lorsque le GPU aura terminé de les utiliser, à l’aide du mécanisme de destruction différée de D3D11. Toutefois, si vous tentez de libérer l’appareil D3D11On12 lui-même pendant que le GPU est toujours en cours d’exécution, la destruction peut se bloquer jusqu’à ce que le GPU se termine.
Limites
La couche D3D11On12 implémente un très grand sous-ensemble de l’API D3D11, mais il existe quelques lacunes connues (en plus des bogues dans l’implémentation qui peuvent entraîner un rendu incorrect).
À partir du Windows 10, version 1809 (10.0 ; Build 17763), tant que D3D11On12 s’exécute sur un pilote qui prend en charge le modèle de nuanceur 6.0 ou version ultérieure, il peut exécuter des nuanceurs qui utilisent des interfaces. Dans les versions antérieures de Windows, la fonctionnalité d’interfaces de nuanceur n’est pas implémentée dans D3D11On12, et la tentative d’utilisation de la fonctionnalité entraîne des erreurs et des messages de débogage.
Depuis Windows 10, version 1803 (10.0 ; Build 17134), les chaînes d’échange sont prises en charge sur les appareils D3D11On12. Dans les versions antérieures de Windows, ce n’est pas le cas.
D3D11On12 n’a pas été optimisé pour les performances. Il y aura probablement une surcharge processeur modérée par rapport à un pilote D3D11 standard, une surcharge gpu minimale, et il est connu qu’il y a une surcharge de mémoire importante. Par conséquent, il n’est pas recommandé d’utiliser D3D11On12 pour les scènes 3D compliquées, mais plutôt pour les scènes simples ou le rendu 2D.
API
Les API qui composent la couche 11on12 sont décrites dans référence 11on12.
Rubriques connexes