Partager via


Modifications importantes entre Direct3D 11 et Direct3D 12

Direct3D 12 représente un écart significatif par rapport au modèle de programmation Direct3D 11. Direct3D 12 permet aux applications de se rapprocher plus que jamais du matériel. En étant plus proche du matériel, Direct3D 12 est plus rapide et plus efficace. Toutefois, l’inconvénient de votre application avec une vitesse et une efficacité accrues avec Direct3D 12 est que vous êtes responsable d’un plus grand nombre de tâches que vous ne l’étiez avec Direct3D 11.

Direct3D 12 est un retour à la programmation de bas niveau ; il vous donne plus de contrôle sur les éléments graphiques de vos jeux et applications en introduisant ces nouvelles fonctionnalités : des objets pour représenter l’état global du pipeline, des listes de commandes et des bundles pour la soumission de travail, et des tas de descripteurs et des tables pour l’accès aux ressources.

Votre application a augmenté la vitesse et l’efficacité avec Direct3D 12, mais vous êtes responsable d’un plus grand nombre de tâches qu’avec Direct3D 11.

Synchronisation explicite

  • Dans Direct3D 12, la synchronisation PROCESSEUR-GPU est désormais la responsabilité explicite de l’application et n’est plus implicitement effectuée par le runtime, comme dans Direct3D 11. Cela signifie également qu’aucune vérification automatique des risques de pipeline n’est effectuée par Direct3D 12. C’est donc là encore la responsabilité des applications.
  • Dans Direct3D 12, les applications sont responsables du pipelining des mises à jour des données. Autrement dit, le modèle « Map/Lock-DISCARD » dans Direct3D 11 doit être exécuté manuellement dans Direct3D 12. Dans Direct3D 11, si le GPU utilise toujours la mémoire tampon lorsque vous appelez ID3D11DeviceContext::Map avec D3D11_MAP_WRITE_DISCARD, le runtime retourne un pointeur vers une nouvelle région de mémoire au lieu des anciennes données de mémoire tampon. Cela permet au GPU de continuer à utiliser les anciennes données pendant que l’application place les données dans la nouvelle mémoire tampon. Aucune gestion de mémoire supplémentaire n’est requise dans l’application ; L’ancienne mémoire tampon est réutilisée ou détruite automatiquement lorsque le GPU est terminé.
  • Dans Direct3D 12, toutes les mises à jour dynamiques (y compris les mémoires tampons constantes, les tampons de vertex dynamiques, les textures dynamiques, etc.) sont explicitement contrôlées par l’application. Ces mises à jour dynamiques incluent les clôtures gpu ou la mise en mémoire tampon requises. L’application est chargée de conserver la mémoire disponible jusqu’à ce qu’elle ne soit plus nécessaire.
  • Direct3D 12 utilise le comptage des références de style COM uniquement pour la durée de vie des interfaces (en utilisant le modèle de référence faible de Direct3D lié à la durée de vie de l’appareil). Toutes les durées de vie de la mémoire des ressources et des descriptions sont la seule responsabilité de l’application à gérer pendant la durée appropriée, et ne sont pas comptabilisées en référence. Direct3D 11 utilise également le comptage des références pour gérer les durées de vie des dépendances d’interface.

Gestion de la résidence de la mémoire physique

Une application Direct3D 12 doit empêcher les conditions de concurrence entre plusieurs files d’attente, plusieurs adaptateurs et les threads de processeur. D3D12 ne synchronise plus le processeur et le GPU, ni ne prend en charge les mécanismes pratiques pour le renommage des ressources ou la mise en mémoire tampon multiple. Des clôtures doivent être utilisées pour éviter que plusieurs unités de traitement ne surécrire la mémoire avant qu’une autre unité de traitement ne finissent de l’utiliser.

L’application Direct3D 12 doit s’assurer que les données résident en mémoire pendant que le GPU les lit. La mémoire utilisée par chaque objet est rendue résidente lors de la création de l’objet. Les applications qui appellent ces méthodes doivent utiliser des clôtures pour s’assurer que le GPU n’accède pas aux objets qui ont été supprimés.

Les barrières de ressources sont un autre type de synchronisation nécessaire, utilisé pour synchroniser les transitions de ressources et de sous-ressources à un niveau très granulaire.

Reportez-vous à Gestion de la mémoire dans Direct3D 12.

Objets d’état de pipeline

Direct3D 11 permet la manipulation de l’état du pipeline via un grand ensemble d’objets indépendants. Par exemple, l’état de l’assembleur d’entrée, l’état du nuanceur de pixels, l’état du rastériseur et l’état de fusion de sortie peuvent tous être modifiés indépendamment. Cette conception fournit une représentation pratique et relativement élevée du pipeline graphique, mais elle n’utilise pas les fonctionnalités du matériel moderne, principalement parce que les différents états sont souvent interdépendants. Par exemple, de nombreux GPU combinent le nuanceur de pixels et l’état de fusion de sortie en une seule représentation matérielle. Toutefois, étant donné que l’API Direct3D 11 permet de définir ces étapes de pipeline séparément, le pilote d’affichage ne peut pas résoudre les problèmes d’état du pipeline tant que l’état n’est pas finalisé, ce qui n’est pas le cas jusqu’au moment du dessin. Ce schéma retarde la configuration de l’état du matériel, ce qui signifie une surcharge supplémentaire et moins d’appels de dessin maximum par image.

Direct3D 12 traite ce schéma en unifiant une grande partie de l’état du pipeline en objets d’état de pipeline immuables, qui sont finalisés lors de la création. Le matériel et les pilotes peuvent ensuite convertir immédiatement l’authentification unique en n’importe quel état et instructions matérielles natifs requis pour exécuter le travail GPU. Vous pouvez toujours modifier dynamiquement l’authentification unique en cours d’utilisation, mais pour ce faire, le matériel doit uniquement copier la quantité minimale d’état précalculé directement dans les registres matériels, plutôt que de calculer l’état du matériel à la volée. En utilisant des osSP, la surcharge des appels de dessin est considérablement réduite, et de nombreux autres appels de dessin peuvent se produire par image. Pour plus d’informations sur les psO, consultez Gestion de l’état du pipeline graphique dans Direct3D 12.

Listes de commandes et offres groupées

Dans Direct3D 11, toute la soumission de travail est effectuée via le contexte immédiat, qui représente un seul flux de commandes qui vont au GPU. Pour obtenir une mise à l’échelle multithread, les jeux disposent également de contextes différés . Les contextes différés dans Direct3D 11 ne sont pas parfaitement mappés au matériel, de sorte que relativement peu de travail peut y être effectué.

Direct3D 12 introduit un nouveau modèle de soumission de travail basé sur des listes de commandes qui contiennent l’intégralité des informations nécessaires à l’exécution d’une charge de travail particulière sur le GPU. Chaque nouvelle liste de commandes contient des informations telles que l’authentification unique à utiliser, les ressources de texture et de mémoire tampon nécessaires, ainsi que les arguments pour tous les appels de dessin. Étant donné que chaque liste de commandes est autonome et n’hérite d’aucun état, le pilote peut pré-calculer toutes les commandes GPU nécessaires à l’avance et de manière à thread libre. Le seul processus série nécessaire est la soumission finale de listes de commandes au GPU via la file d’attente de commandes.

En plus des listes de commandes, Direct3D 12 introduit également un deuxième niveau de pré-calcul de travail : les bundles. Contrairement aux listes de commandes, qui sont entièrement autonomes et sont généralement construites, envoyées une fois et ignorées, les bundles fournissent une forme d’héritage d’état qui autorise la réutilisation. Par exemple, si un jeu souhaite dessiner deux modèles de personnages avec des textures différentes, une approche consiste à enregistrer une liste de commandes avec deux jeux d’appels de dessin identiques. Mais une autre approche consiste à « enregistrer » un bundle qui dessine un modèle de caractère unique, puis à « lire » le bundle deux fois dans la liste de commandes à l’aide de différentes ressources. Dans ce dernier cas, le pilote d’affichage n’a qu’à calculer les instructions appropriées une seule fois, et la création de la liste de commandes équivaut essentiellement à deux appels de fonction à faible coût.

Pour plus d’informations sur les listes de commandes et les bundles, consultez Soumission de travail dans Direct3D 12.

Segments et tables de descripteur

La liaison de ressources dans Direct3D 11 est très abstraite et pratique, mais laisse de nombreuses fonctionnalités matérielles modernes sous-utilisées. Dans Direct3D 11, les jeux créent des objets de vue de ressources, puis lient ces vues à plusieurs emplacements à différentes étapes du nuanceur dans le pipeline. Les nuanceurs, à leur tour, lisent les données de ces emplacements de liaison explicites, qui sont fixes au moment du dessin. Ce modèle signifie que chaque fois qu’un jeu dessine à l’aide de ressources différentes, il doit lier à nouveau différentes vues à différents emplacements, puis appeler à nouveau draw. Ce cas représente également une surcharge qui peut être éliminée en utilisant pleinement les fonctionnalités matérielles modernes.

Direct3D 12 modifie le modèle de liaison pour qu’il corresponde au matériel moderne et améliore considérablement les performances. Au lieu d’exiger des vues de ressources autonomes et un mappage explicite aux emplacements, Direct3D 12 fournit un tas de descripteur dans lequel les jeux créent leurs différentes vues de ressources. Ce schéma fournit un mécanisme permettant au GPU d’écrire directement la description de la ressource native matérielle (descripteur) dans la mémoire à l’avance. Pour déclarer les ressources à utiliser par le pipeline pour un appel de dessin particulier, les jeux spécifient une ou plusieurs tables de descripteurs qui représentent des sous-plages du tas de descripteur complet. Étant donné que le tas de descripteur a déjà été rempli avec les données de descripteurs spécifiques au matériel appropriées, la modification des tables de descripteurs est une opération extrêmement peu coûteuse.

En plus des performances améliorées offertes par les tas et les tables de descripteurs, Direct3D 12 permet également d’indexer dynamiquement les ressources dans les nuanceurs, ce qui offre une flexibilité sans précédent et déverrouille de nouvelles techniques de rendu. Par exemple, les moteurs de rendu différé modernes encodent généralement un identificateur de matériau ou d’objet d’un type quelconque dans le g-buffer intermédiaire. Dans Direct3D 11, ces moteurs doivent veiller à éviter d’utiliser trop de matériaux, car en inclure trop dans un g-tampon peut ralentir considérablement la passe de rendu finale. Avec des ressources indexables dynamiquement, une scène avec un millier de matériaux peut être finalisée aussi rapidement qu’une scène avec seulement dix.

Pour plus d’informations sur les tas et les tables de descripteur, consultez Liaison de ressources et Différences dans le modèle de liaison de Direct3D 11.

Portage à partir de Direct3D 11

Le portage à partir de Direct3D 11 est un processus impliqué, décrit dans Portage de Direct3D 11 vers Direct3D 12. Reportez-vous également à la plage d’options dans Utilisation de Direct3D 11, Direct3D 10 et Direct2D.

Comprendre Direct3D 12