Changements importants entre Direct3D 9 et Direct3D 11
Résumé
- Planifiez votre portage DirectX
- Changements importants entre Direct3D 9 et Direct3D 11
- Cartographie des fonctionnalités
Cette rubrique explique les différences de haut niveau entre DirectX 9 et DirectX 11.
Direct3D 11 est fondamentalement le même type d’API que Direct3D 9 - une interface virtualisée de bas niveau avec le matériel graphique. Elle vous permet toujours d’effectuer des opérations de dessin graphique sur une variété d’implémentations matérielles. La structure de l’API graphique a changé depuis Direct3D 9 ; le concept de contexte d’appareil a été élargi et une API a été ajoutée spécifiquement pour l’infrastructure graphique. Les ressources stockées sur l’appareil Direct3D disposent d’un nouveau mécanisme de polymorphisme des données appelé vue de ressource.
Fonctions principales de l’API
Dans Direct3D 9, vous deviez créer une interface avec l’API Direct3D avant de pouvoir l’utiliser. Dans votre jeu Direct3D 11 Universal Windows Platform (UWP), vous appelez une fonction statique appelée D3D11CreateDevice pour créer l’appareil et le contexte de l’appareil.
Appareils et contexte d’appareil
Un appareil Direct3D 11 représente un adaptateur graphique virtualisé. Il est utilisé pour créer des ressources dans la mémoire vidéo, par exemple : échanger des textures avec le GPU, créer des vues sur les ressources de texture et les chaînes d’échange, et créer des échantillonneurs de texture. Pour une liste complète des utilisations d’une interface de périphérique Direct3D 11, voir ID3D11Device et ID3D11Device1.
Un contexte de périphérique Direct3D 11. est utilisé pour définir l’état du pipeline et générer des commandes de rendu. Par exemple, une chaîne de rendu Direct3D 11 utilise un contexte d’appareil pour configurer la chaîne de rendu et dessiner la scène (voir ci-dessous). Le contexte de l’appareil est utilisé pour accéder (mapper) à la mémoire vidéo utilisée par les ressources de l’appareil Direct3D ; il est également utilisé pour mettre à jour les données des sous-ressources, par exemple les données de la mémoire tampon constante. Pour une liste complète des utilisations d’un contexte d’appareil Direct3D 11, voir ID3D11DeviceContext et ID3D11DeviceContext1. Notez que la plupart de nos échantillons utilisent un contexte immédiat pour effectuer le rendu directement sur l’appareil, mais Direct3D 11 prend également en charge les contextes d’appareil différés, qui sont principalement utilisés pour le multithreading.
Dans Direct3D 11, la poignée de l’appareil et la poignée du contexte de l’appareil sont toutes deux obtenues en appelant D3D11CreateDevice. Cette méthode vous permet également de requérir un ensemble spécifique de fonctionnalités matérielles et de récupérer des informations sur les niveaux de fonctionnalités Direct3D pris en charge par l’adaptateur graphique. Voir Introduction à un appareil dans Direct3D 11 pour plus d’informations sur les appareils, les contextes d’appareils et les considérations de threading.
Infrastructure des appareils, tampons de trame et vues de la cible de rendu
Dans Direct3D 11, l’adaptateur d’appareil et la configuration matérielle sont définis avec l’API DirectX Graphics Infrastructure (DXGI) à l’aide des interfaces COM IDXGIAdapter et IDXGIDevice1. Les tampons et autres ressources de la fenêtre (visibles ou hors écran) sont créés et configurés par des interfaces DXGI spécifiques ; l’implémentation du modèle d’usine IDXGIFactory2 acquiert les ressources DXGI telles que le tampon de trame. Comme DXGI possède la chaîne d’échange, une interface DXGI est utilisée pour présenter les trames à l’écran - voir IDXGISwapChain1.
Utilisez IDXGIFactory2 pour créer une chaîne d’échange compatible avec votre jeu. Vous devez créer une chaîne d’échange pour une fenêtre principale ou pour la composition (interopérabilité XAML), au lieu de créer une chaîne d’échange pour un HWND.
Ressources d’appareil et vues de ressources
Direct3D 11 prend en charge un niveau supplémentaire de polymorphisme sur les ressources de mémoire vidéo, connu sous le nom de vues. En fait, alors que vous disposiez d’un seul objet Direct3D 9 pour une texture, vous avez maintenant deux objets : la ressource texture, qui contient les données, et la vue ressource, qui indique comment la vue est utilisée pour le rendu. Une vue basée sur une ressource permet d’utiliser cette ressource dans un but spécifique. Par exemple, une ressource de texture 2D est créée en tant que ID3D11Texture2D, puis une vue de ressource de shader (ID3D11ShaderResourceView) est créée sur cette ressource afin qu’elle puisse être utilisée en tant que texture dans un shader. Une vue de cible de rendu (ID3D11RenderTargetView) peut également être créée sur la même ressource de texture 2D afin qu’elle puisse être utilisée comme surface de dessin. Dans un autre exemple, les mêmes données de pixels sont représentées dans deux formats de pixels différents en utilisant deux vues distinctes sur une seule ressource de texture.
La ressource sous-jacente doit être créée avec des propriétés compatibles avec le type de vues qui seront créées à partir d’elle. Par exemple, si une ID3D11RenderTargetView est appliquée à une surface, cette surface est créée avec l’indicateur D3D11_BIND_RENDER_TARGET. La surface doit également avoir un format de surface DXGI compatible avec le rendu (voir DXGI_FORMAT).
La plupart des ressources que vous utilisez pour le rendu héritent de l’interface ID3D11Resource, qui hérite de ID3D11DeviceChild. Les tampons de sommet, les tampons d’index, les tampons de constante et les shaders sont tous des ressources Direct3D 11. Les dispositions d’entrée et les états d’échantillonnage héritent directement de ID3D11DeviceChild.
Les vues de ressources utilisent une valeur enum DXGI_FORMAT pour indiquer le format des pixels. Tous les D3DFMT ne sont pas pris en charge en tant que DXGI_FORMAT. Par exemple, il n’existe pas de format RVB 24bpp dans DXGI qui soit équivalent à D3DFMT_R8G8B8. Il n’existe pas non plus d’équivalents BGR pour chaque format RVB (DXGI_FORMAT_R10G10B10A2_UNORM est équivalent à D3DFMT_A2B10G10R10, mais il n’y a pas d’équivalent direct à D3DFMT_A2R10G10B10). Vous devez prévoir de convertir tout contenu dans ces anciens formats en formats pris en charge au moment de la création. Pour une liste complète des formats DXGI, consultez l’énumération DXGI_FORMAT.
Les ressources d’appareils Direct3D (et les vues de ressources) sont créées avant le rendu de la scène. Les contextes d’appareil sont utilisés pour configurer la chaîne de rendu, comme expliqué ci-dessous.
Contexte d’appareil et chaîne de rendu
Dans Direct3D 9 et Direct3D 10.x, il y avait un seul objet Direct3D device qui gérait la création de ressources, l’état et le dessin. Dans Direct3D 11, l’interface de l’appareil Direct3D gère toujours la création des ressources, mais toutes les opérations d’état et de dessin sont gérées à l’aide d’un contexte d’appareil Direct3D. Voici un exemple de l’utilisation du contexte d’appareil (interface ID3D11DeviceContext1) pour mettre en place la chaîne de rendu :
- Définir et effacer les vues de la cible de rendu (et la vue du pochoir de profondeur)
- Définir le tampon de vertex, le tampon d’index et la disposition d’entrée pour l’étape de l’assembleur d’entrée (étape IA)
- Lier les nuanceurs de sommets et de pixels au pipeline.
- Lier les tampons constants aux nuanceurs
- Lier les vues de texture et les échantillonneurs au nuanceur de pixels
- Dessiner la scène
Lorsque l’une des méthodes ID3D11DeviceContext::Draw est appelée, la scène est dessinée sur la vue de la cible de rendu. Lorsque vous avez fini de dessiner, l’adaptateur DXGI est utilisé pour présenter la trame terminée en appelant IDXGISwapChain1::Present1.
Gestion de l’état
Direct3D 9 gère les paramètres d’état avec un grand nombre de bascules individuelles définies avec les méthodes SetRenderState, SetSamplerState et SetTextureStageState. Étant donné que Direct3D 11 ne prend pas en charge l’ancien pipeline à fonction fixe, la méthode SetTextureStageState est remplacée par l’écriture de pixel shaders (PS). Il n’y a pas d’équivalent au bloc d’état de Direct3D 9. Direct3D 11 gère l’état par l’utilisation de 4 types d’objets d’état qui fournissent une manière plus rationnelle de regrouper l’état de rendu.
Par exemple, au lieu d’utiliser SetRenderState avec D3DRS_ZENABLE, vous créez un objet DepthStencilState avec ce paramètre et d’autres paramètres d’état connexes et vous l’utilisez pour changer d’état pendant le rendu.
Lorsque vous portez des applications Direct3D 9 vers des objets d’état, sachez que vos différentes combinaisons d’état sont représentées sous forme d’objets d’état immuables. Ils doivent être créés une seule fois et réutilisés tant qu’ils sont valides.
Niveaux de fonctionnalités Direct3D
Direct3D dispose d’un nouveau mécanisme pour déterminer la prise en charge du matériel, appelé niveaux de fonctionnalité. Les niveaux de fonctionnalité simplifient la tâche consistant à déterminer ce que l’adaptateur graphique peut faire en vous permettant de requérir un ensemble bien défini de fonctionnalités du GPU. Par exemple, le niveau de fonctionnalité 9_1 met en œuvre les fonctionnalités fournies par les adaptateurs graphiques Direct3D 9, y compris le modèle de shader 2.x. Étant donné que 9_1 est le niveau de fonctionnalité le plus bas, vous pouvez vous attendre à ce que tous les appareils prennent en charge un vertex shader et un pixel shader, qui étaient les mêmes étapes prises en charge par le modèle de shader programmable de Direct3D 9.
Votre jeu utilisera D3D11CreateDevice pour créer l’appareil Direct3D et le contexte de l’appareil. Lorsque vous appelez cette fonction, vous fournissez une liste des niveaux de fonctionnalité que votre jeu peut prendre en charge. La fonction renvoie le niveau de fonctionnalité le plus élevé de cette liste. Par exemple, si votre jeu peut utiliser des textures BC4/BC5 (une fonctionnalité du matériel DirectX 10), vous devez inclure au moins 9_1 et 10_0 dans la liste des niveaux de fonctionnalité pris en charge. Si le jeu fonctionne sur du matériel DirectX 9 et que les textures BC4/BC5 ne peuvent pas être utilisées, D3D11CreateDevice renverra 9_1. Votre jeu peut alors revenir à un format de texture différent (et à des textures plus petites).
Si vous décidez d’étendre votre jeu Direct3D 9 pour prendre en charge des niveaux de fonctionnalité Direct3D plus élevés, il est préférable de terminer d’abord le portage de votre code graphique Direct3D 9 existant. Une fois que votre jeu fonctionne sous Direct3D 11, il est plus facile d’ajouter des chemins de rendu supplémentaires avec des graphiques améliorés.
Consultez les niveaux de fonctionnalité de Direct3D pour une explication détaillée de la prise en charge des niveaux de fonctionnalité. Voir les fonctionnalités de Direct3D 11 et Direct3D 11.1 pour une liste complète des fonctionnalités de Direct3D 11.
Les niveaux de fonctionnalités et le pipeline programmable
Le matériel a continué à évoluer depuis Direct3D 9, et plusieurs nouvelles étapes optionnelles ont été ajoutées au pipeline graphique programmable. L’ensemble des options dont vous disposez pour le pipeline graphique varie en fonction du niveau de fonctionnalité de Direct3D. Le niveau de fonctionnalité 10.0 inclut l’étape du shader géométrique avec une sortie de flux optionnelle pour un rendu multipasse sur le GPU. Le niveau de fonctionnalité 11_0 inclut le shader de coque et le shader de domaine pour une utilisation avec la tessellation matérielle. Le niveau de fonctionnalité 11_0 inclut également une prise en charge complète des shaders DirectCompute, alors que les niveaux de fonctionnalité 10.x ne prennent en charge qu’une forme limitée de DirectCompute.
Tous les shaders sont écrits en HLSL à l’aide d’un profil de shader correspondant à un niveau de fonctionnalité Direct3D. Les profils de shaders sont compatibles vers le haut, de sorte qu’un shader HLSL compilé à l’aide de vs_4_0_level_9_1 ou ps_4_0_level_9_1 fonctionnera sur tous les appareils. Les profils de shaders ne sont pas compatibles avec les niveaux inférieurs. Ainsi, un shader compilé à l’aide de vs_4_1 ne fonctionnera que sur les appareils de niveau de fonctionnalité 10_1, 11_0 ou 11_1.
Direct3D 9 gère les constantes des shaders à l’aide d’un tableau partagé avec SetVertexShaderConstant et SetPixelShaderConstant. Direct3D 11 utilise des tampons constants, qui sont des ressources comme un tampon de vertex ou un tampon d’index. Les tampons constants sont conçus pour être mis à jour efficacement. Au lieu d’organiser toutes les constantes de shaders dans un tableau global unique, vous organisez vos constantes en groupes logiques et les gérez par le biais d’un ou plusieurs tampons constants. Lorsque vous portez votre jeu Direct3D 9 vers Direct3D 11, prévoyez d’organiser vos constantes de manière à pouvoir les mettre à jour de manière appropriée. Par exemple, regroupez les constantes de shaders qui ne sont pas mises à jour à chaque trame dans un tampon de constantes distinct, afin de ne pas avoir à télécharger constamment ces données vers l’adaptateur graphique en même temps que vos constantes de shaders plus dynamiques.
Remarque La plupart des applications Direct3D 9 font un usage intensif des shaders, mais mélangent occasionnellement l’utilisation de l’ancien comportement à fonction fixe. Notez que Direct3D 11 n’utilise qu’un modèle d’ombrage programmable. Les anciennes fonctionnalités à fonction fixe de Direct3D 9 sont obsolètes.