Historique de DirectX jusqu'à la version DirectX 9

Bonne année 2009 ! DirectX 11 arrive.

“C’est pour cette année” annonce-t-on chez Microsoft. “Je n’ai pas encore commencé à utiliser les shaders, DirectX 10 n’est même pas encore sur ma to-do list : pourquoi sortent-ils encore une nouvelle version ?”, entend-on chez les autres programmeurs. Malheureusement - ou heureusement selon les points de vue - le monde du jeu, des cartes graphiques et des APIs graphiques évoluent constamment. Dans cet article on va faire le point sur l’évolution de l’interface DirectX depuis ses débuts jusqu’à la version 9.

Un peu d’histoire

DirectX 11, c’est le fruit d’une longue histoire. C’est l’histoire du graphisme sur PC. Il n’y a pas si longtemps que ça, on classait les puces graphiques en fonction du nombre de couleurs et de pixels, voire de caractères de texte, que l’on pouvait afficher. La partie qui nous intéresse à savoir le tracé était le plus souvent généré par le CPU ou processeur central généraliste. Il y avait bien les stations de travail pour les applications graphiques de Silicon Graphics, HP et Evans et Sutherland mais ça ne touchait pas le monde du PC que vous pouviez acheter au supermarché du coin. Dans ce monde les « API graphiques » étaient un grand mot, on avait besoin d’instructions pour changer le mode graphique et pour allumer/éteindre un pixel à l’écran. Cela suffisait pour afficher des graphismes simples à la Castle Wolfenstein 3D, mais qui en contrepartie avait besoin d’un CPU assez puissant (mais rien en comparaison de ce que l’on a maintenant). Pendant ce temps, les interfaces graphiques ont commencé à remplacer les vieilles interfaces textuelles et la multiplication des fenêtres et des applications graphiques gourmandes à la CorelDRAW/Photoshop ont créé un nouveau marché : celui des accélérateurs d’interface graphiques (ou GUI accelerator). Capables d’accéder directement à la mémoire sans faire appel au CPU (DMA ou direct memory access), de remplir des rectangles, polygones, tracer des lignes, voire de remplir des zones de l’écran avec des textures (en général une simple copie parfois avec redimensionnement). Ces capacités étaient les bienvenues dans le monde du PC qui devenait de plus en plus graphique mais il y avait un grand besoin de standardisation.

Standardisation des pilotes

Quand quelqu’un écrit une application pour PC, s’il a une puce graphique spécialisée qui accélère certains calculs comme le tracé de polygones texturés, il pouvait avoir le choix d’utiliser les registres de la puce en question qui étaient documentés par le constructeur de la puce ou de faire appel à une interface de programmation standardisée pour laquelle le constructeur a fourni un logiciel pilote (aussi appelé driver comme en anglais). Ce logiciel pilote est donc le plus souvent chargé de faire le lien entre l’interface standardisée et les registres spécifiques du matériel. Notez que cette distinction n’est pas toujours aussi claire. Dans les premiers PC, le matériel était programmé avec les registres spécifiques. Et donc lorsque des clones de ces PCs apparaissaient, ils se devaient d’émuler ces registres spécifiques même s’ils utilisaient une puce d’un constructeur différent. L’interface spécifique devenait donc le standard de facto. Il y a plusieurs niveaux de compatibilité : “pin compatible” ce qui permet de substituer physiquement les puces, ou de juste substituer les registres, juste les codes d’échappement ou juste créer une interception de plus haut niveau, comme les glide wrappers dans l’histoire plus récente. Cette situation peut arriver encore de temps à autre aujourd’hui mais à plus petite échelle.

Le monde du jeu vidéo cependant restait bloqué sur les interfaces bas niveau et s’il y avait de la standardisation (VESA) elle n’accélérait que le strict minimum (changement de mode d’affichage, accès en écriture direct à la mémoire d’affichage, double buffering). Ce qui fait que bien souvent, au début, les jeux vidéo continuaient à tourner sous l’interface textuelle de MS-DOS tandis que les applications “sérieuses” migraient sous Windows 3.1 avec l’accélération GDI. GDI était considérée comme trop lente pour ce que les développeurs de jeu voulaient faire et le fait de tourner sous Windows détournait une partie des ressources nécessaires aux jeux exigeants de l’époque.

WinG - premier standard Windows pour les jeux

La première tentative de faire migrer les développeurs de jeux sous Windows est venue avec WinG (prononcez “ouine-dji”). Là encore la seule “accélération” proposée par WinG était en fait la suppression des couches intermédiaires qui empêchaient les développeurs de travailler directement sur la mémoire d’affichage. C’est-à-dire essayer de rendre une application Windows aussi rapide qu’elle pouvait l’être sous DOS. WinG est ensuite devenu DirectDraw, inclus dans DirectX 1 (aussi appelé GameSDK). Avec DirectX 1, Windows 95 était devenue une plateforme de jeu à part entière sans raison de conserver MS-DOS comme une alternative viable.

La révolution des accélérateurs

Pendant ce temps-là, une autre révolution était en train d’arriver. Matrox, 3Dlabs, 3dfx, NVIDIA, PowerVR, Rendition lançaient quasi simultanément leurs accélérateurs 3D pour PC. Certains “accélérateurs” de cette époque étaient de simples évolutions des accélérateurs de GUI, ces derniers avaient la possibilité d’afficher des polygones texturés, les accélérateurs 3D étendaient cette capacité en ajoutant la possibilité de faire de l’interpolation perspective (interpolation avec coordonnée homogène W), parfois du filtrage (bilinéaire) et des opérations de blending (mélange de couleurs). Certains ne faisaient que ça, laissant le lourd héritage de la compatibilité aux acteurs établis. Chacune de ces entreprises avaient toutes en commun le but de devenir le seul acteur viable. Ce qui pourrait paraître comique aujourd’hui faisait sens à l’époque, chaque puce graphique avait sa propre interface de programmation. Les développeurs de jeu devaient donc choisir leur allégiance ou faire du code facilement adaptable. Ceux qui ont choisi la deuxième voie comme Criterion Studios (RenderWare) ou RenderMorphics (Reality Labs) ont eu un destin un peu particulier on y reviendra.

La situation s’est éclaircie rapidement, les développeurs de jeu ont plébiscité l’offre de 3dfx avec son interface propriétaire Glide. De plus en plus de jeux de l’époque ne proposaient que deux modes : le rendu logiciel (sur le CPU) ou matériel avec Glide.

Arrivée de Direct3D

Microsoft de son côté se retrouvait dans la même situation d’avant DirectDraw puisque tous les jeux migraient vers la 3D que DirectDraw n’accélérait pas. Plutôt que de développer sa propre interface 3D, certaines personnes poussaient Microsoft à adopter OpenGL. OpenGL tournait déjà sous Windows, il y avait une version qui tournait avec un rendu logiciel et des ports miniGL (pilote OpenGL minimal pour accélérateur graphique) qui faisaient tourner GlQuake par exemple. Mais Microsoft ne contrôlait pas OpenGL (initialement créé par Silicon Graphics sa destinée était contrôlée par l’ARB un consortium d’entreprises diverses et variées) : OpenGL ne bougeait pas assez vite (décision par comité), était un investissement lourd à supporter pour un constructeur spécialisé dans les pilotes bas niveau (les full OpenGL ICD n’arriveront pas avant quelques années et avec pas mal de “ratés”), et selon certains ne pouvait pas supporter le degré d’accélération nécessaires par les jeux de l’époque (rappelons que le rendu software était encore important). Mais plutôt que de repartir de zéro, Microsoft avait racheté Rendermorphics, une entreprise qui développait des jeux et un moteur 3D. Reality labs de Rendermorphics était un moteur fonctionnel avec scene graph haut niveau, et une interface bas niveau qui permettait de faire tourner les jeux sur plusieurs types de matériels (une couche d’abstraction matériel ou HAL). Peut-être que le focus en achetant RenderMorphics s’est trop portée vers l’accélération du rendu via le CPU, mais c’est sans doute plus facile à dire rétrospectivement que dans le feu de l’action de l’époque.

Monster truck madness est l'un des premiers jeux a exploiter Direct3D
Monster truck madness est l’un des premiers jeux a exploiter Direct3D

Disparition des interfaces propriétaires

3dfx était encore trop occupé à promouvoir Glide, mais Microsoft pouvait compter sur le support fort d’Intel (avec i740), ATI (avec Rage 3D) et NVIDIA (avec Riva 128). Ces cartes avaient comme particularité de ne tourner qu’avec les API standards (Direct3D et OpenGL via miniGL au début puis Full OpenGL ICD par la suite), cela annonçait la fin des API propriétaires (pour la 3D). De plus au même moment, la notion de carte exclusivement 2D disparaissait, il n’y avait plus que des cartes accélératrices 3D qui faisaient aussi de la 2D. Du même coup, tous les vendeurs qui ne faisaient que de la 2D ont été absorbés ou ont disparu.

Évolution à marche forcée

Les révisions fréquentes de DirectX étaient nécessaires parce que les constructeurs annonçaient régulièrement le support de nouvelles fonctionnalités que l’ancienne version ne supportait pas. DirectX 3 était la première version à proposer Direct3D (Direct3D 1 = Direct3D 3 d’une certaine façon), basée entièrement sur Reality Labs avec le scene graph haut niveau et les execute buffer bas niveau. Direct3D 3 n’a pas plu à grand monde à l’exception de certains développeurs anglais. Microsoft a sauté DirectX 4 pour des problèmes de mauvais planning et a livré DirectX 5 avec une version améliorée de Direct3D. Les execute buffers étaient remplacés par des appels de fonctions explicites comme Clear(), DrawPrimitive(), SetRenderState() ce qui a fait taire les plus critiques de l’époque. Oui, cela semble incroyable aujourd’hui mais en pratique il s’agissait juste d’un réhabillage, les execute buffers étant toujours présents en coulisse mais cachés au programmeur.

Direct3D 6 apportait le multitexturing (possibilité de mixer deux textures en une seule passe, par exemple mélanger une lightmap avec une texture diffuse comme dans Quake 2). Direct3D 7 offrait pour la première fois le support de la transformation et de l’éclairage par le hardware graphique (quelque chose qui était déjà possible sous OpenGL mais en pratique pas encore supporté par les cartes grand public), les textures cubes, les textures “managed”, et un bond dans la complexité des texture stage states. Puis enfin est arrivée la programmabilité dans les texture stage states et dans la transformation et l’éclairage avec Direct3D 8 et ses pixel / vertex shaders.

Premier test des pixel shader dans 3dmark 2001
Premier test des pixel shader dans 3dmark 2001

Direct3D 9 - enfin un standard stable

Direct3D 9 a enfoncé le clou en étendant la programmabilité, en proposant le rendu vers des textures à précision flottantes (16 bits et 32 bits flottants par canal) et en apportant une grande amélioration de l’interface de programmation elle-même. Chaque version de Direct3D était rétro-compatible avec la précédente. Cela veut dire plusieurs choses, 1 - il était possible de créer le même device identique sur toute carte graphique avec un support Direct3D 7 minimal. 2 - les applications écrites pour Direct3D 1-2-3-5-6-7-8 devaient pouvoir tourner sur les cartes graphiques qui avaient un driver compatible Direct3D9 (de même une application D3D 1 tournait sur 5, D3D 5 tournait sur 7 etc.). Cela a pas mal limité certains choix d’architecture de l’API elle-même et d’une certaines façon les drivers et le runtime ont pâti de cette nécessité de supporter plusieurs degrés de features avec la même interface. Mais c’était indispensable pour maintenir le taux de pénétration maximale de Direct3D dans le domaine du jeu - Direct3D étant entré en concurrence avec OpenGL dès ses débuts, concurrence qui ne s’est terminée qu’à la sortie de Direct3D 9.

Un an s’était écoulé entre D3D3 (1996) et D3D5 (1997), un an entre D3D5 et D3D6 (1998), encore un an entre 6 et 7(1999), un peu plus d’un an entre 7 et 8(2001) et un peu plus d’un an entre D3D8 et D3D9 (2002/2003). Comme on peut le voir le rythme était très rapide. Mais ce n’était pas forcément un problème parce que les changements étaient très incrémentaux. Par ailleurs au tout début de la 3D le développement de jeu était rapide et parfois le code graphique était réécrit entre les jeux parce que les paradigmes changeaient rapidement (2.5D à 3D software, 3D software à accéléré 3D, accéléré 3D à shaders).

Stagnation

Puis il y a eu un grand vide. Direct3D 9 était-elle la seule interface de programmation dont vous auriez jamais besoin ? Probablement pas, mais son successeur n’est pas sorti avant 2007 soit trois-quatre ans après son introduction ce qui aurait pu sembler une éternité dans le monde du développement de jeu et des cartes graphiques quelques années auparavant. Mais il y avait des signes qu’il n’y aurait pas besoin de plus pendant quelques temps. Le nombre de concurrents dans le secteur de la 3D grand public est dramatiquement tombé à trois (plus deux-trois qui ramassent les miettes). La rapidité d’innovation devenait plus difficile à maintenir avec des features de plus en plus complexes (la lecture de deux textures en simultané justifiait la sortie d’une nouvelle carte et d’une nouvelle API quelques années auparavant), des puces graphiques de plus en plus grosses (la validation elle-même prend des mois), des gammes qui s’étendent (3dfx avait un seul produit la voodoo1, remplacé plus tard par la voodoo2 dans la même gamme de prix). Et puis un facteur important était que pour la première fois, Microsoft avait tenu à créer une API plus durable en faisant de Direct3D9 la première version de Direct3D qu’aucun hardware ne pouvait accélérer complètement à sa sortie - les shaders 3.0 ont commencé à être supporté par les Geforce 6800 en avril 2004, les textures flottantes avec multisampling par la Radeon X1800 en octobre 2005.

Cela a des avantages et des inconvénients. Dans les inconvénients, d’un point de vue marketing, pendant trois ans, chaque mise à jour de cartes graphiques se distinguait de la version précédente grâce à un artifice marketing (comme Direct3D9 “plus”). Et les trous dans l’API - malgré son excellent design de départ - sont devenus de plus en plus flagrants au cours des années.

Mais dans les avantages, il y a la stabilité que le non-changement d’API a apportée. Bien entendu, il y a des développeurs qui ont résisté et qui ont continué à distribuer des jeux programmés avec Direct3D8 dans les deux ans qui ont suivi la sortie de Direct3D 9. En pratique, il est certain que cette stabilité a contribué à la force de Direct3D, notamment en accroissant son impact sur les développeurs aux dépens d’OpenGL. Encore aujourd’hui, dans des temps incertains, Direct3D9 - qui ressemble de plus en plus à un bateau qui fuit de partout six ans après son introduction - reste l’API de référence pour les développeurs PC, sur plate-forme Windows bien entendu.

Crysis summum du rendu Direct3D 9
Crysis summum du rendu Direct3D 9

Le futur

Allez voir les articles suivant pour vous faire une idée de l’après DirectX 9.

Direct 3D 10 du changement en perspective

Un avant goût de DirectX 11

Comments

Leave your comment