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 aux 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
- en arrière-plan
- Nettoyage
- limitations
- API
- rubriques connexes
Initialisation 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 comme 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
hors de 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 les listes de commandes D3D11 et D3D12 fonctionnent sur les mêmes ressources, il est nécessaire de créer des « ressources encapsulées » à l’aide de l’API CreateWrappedResourceCreateWrappedResource. Cette méthode « promeut » une ressource D3D12 compréhensible dans D3D11. Une ressource encapsulée démarre dans l’état « acquis », une 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 au-dessus d’une mémoire tampon arrière D3D12. Consultez l’exemple D3D11On12 pour obtenir un exemple de code. Voici une description approximative des étapes à suivre pour ce faire :
- Créez un appareil D3D12 (D3D12CreateDevice) et une chaîne d’échange D3D12 (CreateSwapChain avec un ID3D12CommandQueue en 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 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 de retour de la chaîne d’échange actuelle à l’aide d’une liste de commandes D3D12 et exécutez-la.
- Acquérir la ressource encapsulée de la mémoire tampon back actuelle (AcquireWrappedResources).
- Émettez des commandes de rendu D2D.
- Relâchez la ressource encapsulée (ReleaseWrappedResources).
- Videz le contexte immédiat D3D11.
- Present (IDXGISwapChain1 ::P resent1).
Arrière-plan
D3D11On12 fonctionne systématiquement. Chaque appel d’API D3D11 passe par la validation du runtime classique et rend son chemin vers le pilote. Au niveau de la couche pilote, le pilote spécial 11on12 enregistre l’état et émet des opérations de rendu dans les listes de commandes D3D12. Ces listes de commandes sont envoyées si nécessaire (par exemple, une requête GetData
ou une ressource Map
peuvent nécessiter des commandes à vider) 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, et 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 vous assurer que le travail se produit dans l’ordre correct, le contexte immédiat D3D11 doit être vidé avant que d’autres travaux D3D12 puissent être soumis à 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 de la file d’attente doivent finalement être satisfaites, même si le thread de rendu D3D11 bloque indéfiniment. Soyez prudent de ne pas prendre de dépendance lorsque D3D11On12 insère des vidages ou des attentes, car cela peut changer avec les futures versions. En outre, D3D11On12 effectue le suivi et manipule les états des ressources par eux-mêmes. 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 de l’état en fonction des besoins de l’application.
Assainissement
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 les vues de la ressource, doivent être publiées.
- Le traitement de destruction différé doit avoir lieu. La façon la plus simple de s’assurer que cela se produit consiste à appeler le contexte immédiat
Flush
API.
Une fois ces deux étapes terminées, toutes les références effectuées par la ressource encapsulée doivent être libérées et la ressource D3D12 devient exclusivement détenue par le composant D3D12. N’oubliez pas que D3D12 nécessite toujours une attente d’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 sont nettoyés au moment approprié, lorsque le GPU a terminé de les utiliser, à l’aide du mécanisme de destruction différé de D3D11. Toutefois, si vous tentez de libérer l’appareil D3D11On12 lui-même alors que le GPU est toujours en cours d’exécution, la destruction peut bloquer jusqu’à ce que le GPU se termine.
Limitations
La couche D3D11On12 implémente un sous-ensemble très volumineux de l’API D3D11, mais il existe des lacunes connues (en plus des bogues dans l’implémentation qui peuvent provoquer un rendu incorrect).
Depuis Windows 10, version 1809 (10.0 ; Build 17763), tant que D3D11On12 est en cours d’exécution sur un pilote qui prend en charge shader Model 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, elles ne le sont pas.
D3D11On12 n’a pas été optimisé pour les performances. Il y aura probablement une surcharge moyenne du processeur par rapport à un pilote D3D11 standard, une surcharge minimale du GPU et il est connu pour être une surcharge de mémoire importante. Par conséquent, il n’est pas recommandé d’utiliser D3D11On12 pour les scènes 3D complexes, et il est plutôt recommandé pour les scènes simples ou le rendu 2D.
Apis
Les API qui composent la couche 11on12 sont décrites dans 11on12 Reference.
Rubriques connexes