Liens connexes

Dépêche modérée par

Dépêche éditée par

: Un point sur le projet Nouveau

Posté par Mjules (page perso, ). Modéré le 19 février 2008.
0
Nouveau est un projet de pilote X libre visant à supporter les cartes NVidia aussi bien en 2D qu'en 3D. Depuis la dernière dépêche sur le sujet, il y a presque un an, le projet a bien évolué.

Le présent article a pour but de faire le point sur l'avancement de Nouveau et de son pilote, ainsi que sur les évolutions attendues. C'est une traduction de celui de Linux Weekly News qui sera publié jeudi. Le site LWN.net nous a gracieusement autorisé à le traduire et publier la version française avant eux. L'article original a été collégialement écrit par les membres du projet.

Si vous souhaitez nous rencontrer, vous êtes les bienvenus au FOSDEM 2008 où une partie de l'équipe du projet Nouveau se rendra les 23 et 24 février. Stéphane Marchesin y présentera les étapes pour arriver à un pilote libre (Samedi 23, 16h30 -17H30 Xorg Devroom).

> Lire la suite (62 commentaires, moyenne: 3,9).   [dépêche : 41538 caractères]

Cet article fait le point sur l'avancement du projet Nouveau et l'évolution de la pile graphique sous Linux.

== Introduction ==

Nouveau est un projet visant à écrire un pilote X.org libre et complet pour les cartes graphiques Nvidia. L'objectif est de supporter l'accélération 2D et 3D pour toutes les cartes NVidia depuis les NV04 (TNT) aux dernières G80 (Geforce 8), et de supporter les architectures x86-64, PPC et x86.


== Historique ==

Le projet a démarré quand Stéphane Marchesin a voulu désobscurcir une partie du pilote nv, maintenu par NVidia. Malheureusement, un certain nombre de règles étaient en place chez NVidia concernant ce pilote, et ils n'avaient à l'époque aucune intention de les changer. Ils refusèrent les patches de Stéphane.

Il ne restait donc à notre intrépide hacker que le grand choix du libre : forker ! En février 2006, au FOSDEM, Stéphane a dévoilé ses plans pour un pilote libre pour le matériel NVidia appelé Nouveau. Le nom a été suggéré par la fonction de remplacement automatique de son client IRC qui lui proposait le mot « nouveau » lorsqu'il tapait « nv ». Les gens ont aimé et le nom est resté. La présentation au FOSDEM a amené assez de publicité au projet pour attiser la curiosité d'autres développeurs.

Ben Skeggs fut l'un des premiers à s'impliquer. Il avait auparavant travaillé à l'ingénierie inverse des shaders des r300 (un circuit graphique d'ATI) et avait écrit des parties du pilote ; il avait donc une grande expérience avec les pilotes graphiques. Au départ, il s'intéressait uniquement aux shaders des NV40 mais il a par la suite été pris dans le mouvement et a à ce jour travaillé sur à peu près toutes les parties du pilote pour les NV40 et supérieures.

Le projet a attiré d'autres développeurs avec des intérêts à plus ou moins long terme. Un utilisateur indépendant a mis en place une promesse de dons, dont le montant final s'est élevé à 10 000$ US, mais pour des raisons indépendantes de notre volonté nous n'avons pas pu recevoir ces dons.

Le projet étant principalement développé sur IRC, il était assez difficile pour les nouveaux arrivants de se rendre compte des développements antérieurs, lire des logs IRC n'étant pas très pratique. KoalaBR a donc décidé de résumer le développement dans une série d'articles connus sous le nom de TiNDC (The irregular Nouveau Development Companion). Ceux-ci se sont révélés être très utiles pour attirer des nouveaux développeurs et testeurs autour du projet. Le TiNDC est publié toutes les deux à quatre semaines.

Le LCA 2007 a vu la première démonstration réelle de Nouveau. Dave Airlie avait accepté de donner une conférence sur le sujet et a réussi à persuader Ben Skeggs que montrer un glxgears fonctionnel ferait un magnifique final. Ben a travaillé sans répit avec les autres développeurs afin d'avoir une initialisation correcte de la carte de son portable et la présentation fut un véritable succès.

Après avoir manqué de place au Google Summer of Code, X.org a fourni à Nouveau une alternative par l'intermédiaire du Vacation of Code. Celui-ci a vu Arthur Huillet rejoindre l'équipe et travailler sur un support performant de Xv dans Nouveau. Arthur a eu une révélation et il a continué à s'impliquer dans Nouveau après la fin du VoC.

À l'automne 2007, Stuart Bennett et Maarten Maathuis se sont promis d'améliorer le support de Nouveau pour RandR1.2. Depuis, un flot continuel de patches a permis une nette amélioration du code.

Le projet a actuellement 8 contributeurs réguliers (Stéphane Marchesin, Ben Skeggs, Patrice Mandin, Arthur Huillet, Pekka Paalanen, Maarten Maathuis, Peter Winters, Jeremy Kolb, Stuart Bennett) et bien plus de contributeurs occasionnels, testeurs, écrivains et traducteurs.


== Les familles de cartes NVidia ==

Cet article utilisera les noms techniques des GPU (Graphics Processing Unit) NVidia et non les noms commerciaux :
Pour les noms avec « N » ou « G », nous utilisons de préférence la variante « N » (NV4x et NV5x).
http://nouveau.freedesktop.org/wiki/CodeNames pour plus d'informations


== Généralités sur le système graphique ==

Avant de nous intéresser au pilote Nouveau, nous allons voir dans cette section un bref aperçu de la complexité du système graphique sous GNU/Linux.

Celui-ci a un long historique remontant aux serveurs X Unix et au projet XFree86. Ceci a conduit a une situation très différente de celle des autres pilotes sous Linux. Les pilotes graphiques étaient fournis par le projet XFree86, s'exécutaient principalement en espace utilisateur, et ne requéraient que peu voire pas d'interaction avec le noyau. La partie en espace utilisateur, connue sous le nom de DDX (Device-Dependant X), était responsable de l'initialisation de la carte, de la gestion des modes (NDT : fréquence et résolution) et elle fournissait l'accélération des opérations 2D.

Le noyau fournissait également des pilotes framebuffer pour certains systèmes afin d'avoir une console utilisable avant le démarrage de X. Malheureusement, les interactions entre ces pilotes et ceux de X étaient plus ou moins aléatoires et de nombreux problèmes pouvaient survenir, notamment en cas de conflit sur qui doit diriger le matériel.

Le projet DRI a démarré afin d'ajouter le support pour le rendu direct dans les applications 3D sous GNU/Linux. Rendu direct signifie qu'une application peut parler directement à la partie 3D du matériel, sans passer par le serveur X. OpenGL est l'API 3D standard mais elle est trop complexe et trop grande pour être implémentée dans le noyau, sans compter les différents GPU qui fournissent des interfaces bas-niveaux très différentes. Ainsi, à cause de la complexité de l'interface haut-niveau et de l'absence de standardisation des API matérielles, un composant noyau (DRM, Direct Rendering Manager) et un pilote en espace utilisateur (DRI, Direct Rendering Infrastructure) furent nécessaires pour exposer sans risque les interfaces matérielles et fournir l'API OpenGL.

Les limitations de cette architecture sont apparues au cours des dernières années et le consensus actuel est que l'initialisation du GPU, la gestion de la mémoire et celle des modes doivent migrer dans le noyau. Cela permettra une meilleure cohabitation entre les pilotes X et le framebuffer, un meilleur support de la mise en veille/réveil, une plus grande facilité à rapporter les erreurs noyau (le noyau sera capable d'afficher un message d'erreur à l'écran même si X est lancé), et plus de souplesse pour gérer les futures technologies des cartes graphiques.

Le gestionnaire de mémoire des GPU, implémenté par Tungsten Graphics, est connu sous le nom de TTM ( http://lwn.net/Articles/256772/ ). Bien qu'initialement destiné au matériel Intel, il est conçu comme un gestionnaire de mémoire vidéo généraliste.

Au dessus du gestionnaire de mémoire, un architecture de gestion des modes dans le noyau a été implémentée. Elle est basée sur le travail réalisé avec RandR1.2 dans le serveur X.org.


== Architecture du GPU ==

Les cartes graphiques peuvent être programmées de multiples façons mais la plus grande partie de l'initialisation et de la gestion des modes est faite via MMIO (entrées/sorties projetées en mémoire, Memory Mapped I/O), qui correspond à un ensemble de registres accessibles par le CPU dans son espace d'adressage mémoire standard. Ceux-ci sont ensuite divisés en groupes gérant diverses fonctions telles que gestion des modes, contrôle des sorties vidéos ou encore configuration des fréquences.

Une explication plus complète peut être trouvée à l'adresse suivante : http://en.wikipedia.org/wiki/Memory-mapped_IO

Les GPU les plus récents fournissent également des possibilités de traitement de commandes grâce auxquelles il est possible de décharger le CPU de différentes tâches qui seront alors exécutées sur le GPU, réduisant les ressources CPU nécessaires pour les opérations graphiques.
Ces interfaces sont généralement des FIFO (First In, First Out) implémentées comme des tampons circulaires dans lesquels les commandes sont placées par le CPU et exécutées par le GPU. Elles sont situées dans une zone de mémoire partagée (mémoire AGP, PCIGART ou RAM vidéo). Le GPU possède également un ensemble d'informations d'état, généralement appelées contextes, qui sont utilisées pour traiter les commandes.

La plupart des GPU modernes contiennent une seule machine à états pour traiter les commandes. Le matériel NVidia, quant à lui, a toujours possédé plusieurs « canaux » indépendants qui consistent en une FIFO privée (push buffer), un contexte graphique et un ensemble d'objets de contexte. Le « push buffer » contient les commandes à exécuter par la carte, le contexte graphique stocke les données spécifiques à l'application telles que des matrices, des configuration d'unités de textures, des paramètres de blending, des informations sur les shaders, etc. Chaque canal contient 8 sous-canaux auxquels sont liés les objets graphiques avant leur traitement par la commande dans la FIFO.

Chaque carte NVidia dispose, suivant le modèle, de 16 à 128 canaux assignés à différentes tâches de rendu. Chaque client 3D possède un canal associé, quelques canaux sont réservés pour le noyau et pour le serveur X. Les canaux sont intervertis (« changement de contexte ») par voie logicielle à la suite d'une interruption sur les vieilles cartes, et automatiquement par la carte elle-même pour celles postérieures aux NV30.

Et maintenant, que placer dans la FIFO ?
Chaque carte NVidia dispose d'un ensemble d'objets, chacun d'entre eux fournissant différentes méthodes liées à une tâche donnée, par exemple, transfert mémoire DMA ou rendu.
Ces méthodes sont celles utilisées par le pilote (ou, à un niveau plus élevé, par l'application). Quand un client se connecte, il utilise un ioctl() pour créer un canal. Par la suite, le client crée les objets dont il a besoin à l'aide d'un autre ioctl().

Actuellement, nous avons deux types de client possibles :
X (via le pilote DDX) et OpenGL via DRI/MESA. Un pilote framebuffer accéléré utilisant la nouvelle architecture de gestion de mode (nouveaufb) sera également un client dans le futur, permettant d'éviter les conflits rencontrés avec nvidiafb.

Détaillons quelques uns de ces objets :

nom de l'objet:
NV_IMAGE_BLIT
Description courte:
Moteur 2D, combine plusieurs images en une autre.
Disponible sur:
NV03,NV04,NV10,NV20

nom de l'objet:
NV12_IMAGE_BLIT
Description courte:
Version améliorée du précédent.
Disponible sur:
NV11,NV20,NV20,NV30,NV40

nom de l'objet:
NV_MEMORY_TO_MEMORY_FORMAT
Description courte:
Transfert mémoire DMA.
Disponible sur:
V04,NV10,NV20,NV30,NV40,NV50

Dans cette liste, vous pouvez remarquer que certains objets sont disponibles sur toutes les cartes (NV_MEMORY_TO_MEMORY_FORMAT) tandis que d'autres ne le sont que sur certaines. Par exemple, chaque famille de carte a son propre objet moteur 3D : NV10TCL sur NV1x, NV20TCL sur NV2x, etc.
Chaque objet est identifié par un nombre unique : sa « classe ». Cet ID est 0x5f pour NV_IMAGE_BLIT, 0x9f pour NV12_IMAGE_BLIT et 0x39 pour NV_MEMORY_TO_MEMORY_FORMAT.
Si vous voulez utiliser les fonctionnalités d'un objet donné, vous devez tout d'abord le lier à un sous-canal. La carte fournit un certain nombre de sous-canaux, qui correspondent à un certain nombre d'objet actifs (ou liés).

Chaque méthode fournie par un objet possède un offset qui doit être précisé dans la commande.

Une commande dans la FIFO est composée d'un en-tête suivi par un ou plusieurs paramètres. L'en-tête contient généralement le numéro du sous-canal, l'offset de la méthode à appeler et le nombre de paramètres (une entête peut également définir un saut dans le FIFO mais cela sort du cadre de cette explication).

De façon à limiter la quantité d'entêtes à écrire et donc améliorer les performances, les cartes NVidia peuvent appeler plusieurs méthodes consécutives en une fois si on a correctement fourni plusieurs paramètres.

Comment se réfère-t-on à un objet ?
Les données écrites dans la FIFO ne contiennent aucune information à ce sujet...

Lier un objet au sous-canal 1 est réalisé par l'écriture de son ID comme argument de la méthode 0. Par exemple : 00044000 5c00000c lie l'objet dont l'ID est 5c00000c au sous-canal 2. Cet ID est alors utilisé comme clé dans une table de hachage conservée dans la mémoire de la carte et qui est remplie lors de la création des objets. C'est comme ça que l'objet est identifié.

La création d'un objet a besoin de zones mémoire spéciales :

RAMIN

RAMIN signifie « mémoire d'instance », c'est une zone de mémoire à travers laquelle le moteur graphique est configuré. Une zone RAMIN est présente sur toutes les puces NVidia d'une façon ou d'une autre mais elle a évolué au fur et à mesure de la sortie des nouvelles puces.
En bref, RAMIN est ce qui contient les objets. Ces derniers ne sont généralement pas très gros (128 octets en général, jusqu'à quelques kilooctets dans le cas des objets DMA qui contiennent une liste de pages physiques).

RAMIN contient également quelques zones spécifiques à mentionner :


RAMFC - Table des contextes FIFO
RAMHT - FIFO hash table
Des information supplémentaires sont disponibles sur ces liens :
http://nouveau.freedesktop.org/wiki/NvObjectTypes
http://nouveau.freedesktop.org/wiki/HonzaHavlicek


== Sources d'informations et outils d'ingénierie inverse ==

Étant donné que très peu d'informations sont disponibles sur la conception et l'implémentation du matériel NVidia, le projet Nouveau a développé un certain nombre d'outils afin de mieux comprendre l'architecture des cartes et comment les programmer. Ce sont ces outils, accompagnés d'informations préexistantes, qui sont utilisés pour écrire le pilote.

Haiku/BeOS dispose d'un pilote issu du SDK NVidia disponible pour les cartes NV03/04 et des informations fournies par le pilote nv non obscurci qui a fait un bref passage dans XFree86. Ce pilote possède un code de gestion des modes amélioré par rapport à nv et un pilote 3D basique utilisant des objets fixes et un contexte unique.

D'autres informations sont disponibles dans l'utilitaire nvclock qui permet l'overclocking sous GNU/Linux des GPU NVidia. Son principal auteur, Roderick Colenbrander (Thunderbird) a aidé Nouveau pour la gestion des fréquences, de l'i2c, et de la sortie TV (dont le support n'est pas encore implémenté dans Nouveau).

=== REnouveau ===

Le premier utilitaire qui a été développé est REnouveau. Il permet l'ingénierie inverse du pilote binaire nvidia par la méthode de la boîte noire : envoyer des commandes au pilote d'un côté et étudier ce que le pilote commande à la carte de l'autre. Il utilise pour cela un grand nombre de tests OpenGL couvrant la majeure partie des capacités du GPU et génère un ensemble de fichiers résultats à envoyer aux développeurs de Nouveau.

Il fonctionne en présentant les registres et les FIFO assignés à l'application courante.
Il enregistre ensuite l'état des FIFO et des registres, exécute un programme OpenGL simple et compare l'état final avec l'état initial. Enfin, il écrit l'information dans un format pouvant être lu par un humain en utilisant une base de donnée XML des registres/commandes. (Certains développeurs objecteront que l'hexadécimal est tout à fait lisible pour eux).

Cet outil a comme avantage d'être simple pour l'utilisateur qui peut le lancer sur de nombreuses configurations, sans avoir besoin d'être root. Il ne perturbe pas le pilote binaire et ne nécessite pas de connaissances techniques approfondies.

=== MMioTrace ===

MMioTrace est un outil utilisé pour tracer les accès MMIO dans le noyau. Le pilote NVidia contient en effet un module noyau qui est responsable de presque toute l'initialisation de la carte, la gestion des modes, et qui ne peut pas être observé simplement depuis un outil en espace utilisateur comme REnouveau.
MMioTrace utilise relayFS et debugFS pour remonter les données d'observation vers l'espace utilisateur.

MMioTrace agit en remplaçant, dans le pilote à observer, les appels vers les fonctions noyau ioremap, ioremap_nocache et iounmap par des appels à des fonctions de MMioTrace. Lorsque le pilote modifié appelle ioremap() pour accéder aux registres MMIO, les pages à accéder sont alors présentées comme absentes dans l'espace d'adresse du noyau. MMioTrace peut être paramétré pour ne tracer que les adresses qui pourront être touchées par le pilote, réduisant ainsi le volume du fichier final.

Lorsque le module du pilote essaye d'accéder à l'espace des registres, une erreur de page va se produire. Le gestionnaire d'erreur de page va alors détecter l'adresse et enregistrer l'action tentée. La page est ensuite marquée comme présente, et l'instruction bloquée va être exécutée. La page est ensuite de nouveau marquée comme absente et le cycle peut recommencer au prochain accès.

L'une des restrictions de MMioTrace est qu'il ne peut pas tracer les adresses historiques ISA, marquer celles-ci comme absentes faisant crasher le noyau. Une solution est peut être en vue mais elle nécessiterait de patcher le noyau.

MMioTrace n'est pas seulement utilisable pour les pilotes graphiques mais également pour tous les types de pilotes s'exécutant dans le noyau.
Jusqu'à la version 2.6.23 du noyau Linux, MMioTrace était fourni sous la forme d'un module externe. La version 2.6.24 a vu le retrait des fonctions nécessaires à MMioTrace, ce qui signifie qu'il devra être inclus dans le 2.6.25 ou suivant pour continuer à fonctionner.

Si vous êtes intéressé par plus d'informations, MMioTrace possède une page web dédiée :
http://nouveau.freedesktop.org/wiki/MMioTrace

=== Valgrind-mmt ===

Valgrind-mmt est un greffon pour la suite de débogage Valgrind. Il trace les accès MMIO depuis un processus en espace utilisateur, comme par exemple le serveur X.org où le pilote NVidia DDX est chargé. Cet outil a été développé à l'origine par Dave Airlie pour observer le matériel ATI et ensuite étendu par nombre de développeurs. Il est utilisé dans le cadre de Nouveau, d'une façon plus ou moins similaire à REnouveau, pour extraire le contenu des FIFO.
Valgrind-mmt permet d'observer de façon fiable la FIFO de X.org, ce que REnouveau n'arrive pas très bien à faire. Observer celle-ci est parfois nécessaire pour voir comment certaines fonctions 2D sont implémentées.


== Utiliser MMioTrace pour rajouter une fonctionnalité ==

Les commandes sont en général envoyées à la carte en écrivant dans la FIFO, pas en écrivant les registres MMIO directement, mais certaines tâches telles que l'initialisation de la carte (sélection d'un mode d'écran) nécessitent d'intervenir sur les registres MMIO.

L'exemple ci-dessous montre comment MMioTrace a été utilisé pour effectuer l'ingénierie inverse de l'overlay vidéo YV12, qui existe sur certaines cartes NVidia.

Les vidéos ne sont en général pas stockées en RGB. La plupart des codecs vidéo fonctionnent dans l'espace de couleur YUV, où Y correspond à la luminance (image monochrome), et U et V sont les informations de chrominance (la couleur). La perception de l'oeil humain est plus fine pour la luminance que pour la chrominance, donc la plupart des codecs suppriment une fraction des informations U et V pour gagner un peu d'espace. Quand X-Video demande à la carte d'afficher une image de vidéo, il lui passe un tampon contenant des données YUV, en général en format YV12 ou YUY2.

Bien qu'assez mal fait, le site http://www.fourcc.org/ contient des informations détaillées à propos de ces deux formats. Dans le cadre de cet article, tout ce qui nous intéresse est que YUY2 conserve un échantillon de chrominance (U ou V alternativement) par échantillon de luminance, ce qui signifie que la carte reçoit "YUYVYUYV" (16 bpp). YV12 quant à lui conserve deux échantillons de chrominance (un U, un V) par bloc de luminance de taille 2x2, ce qui donne 12 bits par pixel de video. YV12 est donc 25% plus petit que YUY2, et c'est de très loin le format le plus utilisé par les codecs vidéo. À vrai dire nous n'avons pour l'instant pas trouvé de codec qui sorte autre chose que de l'YV12 (ou du I420, qui est conceptuellement identique - les positions de U et V sont inversées dans le tampon).

Au début de l'été 2007, le support Xv de Nouveau était hérité de nv. En plus d'être extrêmement lent, nv ne supportait que le format YUY2, et convertissait les données YV12 en YUY2 logiciellement, avant de les envoyer à la carte. En travaillant sur l'amélioration des performances, nous nous sommes rapidement demandés si les cartes NVidia supportaient YV12 matériellement. En effet, cela aurait permis de réduire le volume des transferts sur le bus de 25%, ceux-ci jouant un rôle très important dans le débit de Xv, surtout sur les cartes PCI.

Nous avons vérifié cela en mesurant la performance du pilote propriétaire lors de la lecture de vidéos YV12 et YUY2 (en utilisant mplayer -yuy2). Les résultats ont été très clairs :

nvidia propriétaire overlay YUY2 (16 bpp):
real 0m20.591s

nvidia propriétaire overlay YV12 (12 bpp):
real 0m15.409s

Pas besoin de sortir votre calculatrice, il y a une différence de 25%, ce qui correspond à la différence de taille de données. L'explication la plus simple est que ce qui transite sur le bus est en format YV12 : la carte supporte YV12 matériellement.

La situation était donc que nous avions un pilote Xv qui supportait uniquement la vidéo YUY2, et nous savions (du moins pensions, avec un certain niveau de certitude - et d'espérance) que le matériel supportait YV12 nativement. Malheureusement aucun pilote existant, tel que rivatv, n'avait de code pour l'overlay YV12 : il y avait de l'ingénierie inverse à faire.

MMioTrace ne rentre pas en jeu tout de suite : comme indiqué précédemment, la plupart des commandes sont envoyées en écrivant dans la FIFO, pas en touchant aux registres. La première chose à faire était donc d'utiliser valgrind-mmt, pour regarder si la FIFO X contenait certaines commandes relatives à la vidéo.

C'était le cas, mais ces commandes étaient des méthodes logicielles, c'est-à-dire de fausses méthodes pour lesquelles la carte génère une interruption qui demande au noyau de les exécuter. C'est assez similaire à un appel ioctl() vers le module noyau du pilote, sauf que c'est synchronisé avec la FIFO (c'est-à-dire avec le GPU) plutôt qu'avec le CPU. Première conclusion : la sortie vidéo est faite via le module noyau.

Nous avons alors MMioTracé le pilote propriétaire lors de la lecture de vidéos YUY2 et YV12 (de même taille, même position de fenêtre, ... (la seule différence étant le format), et comparé les sorties.

Au milieu des 150Ko de données (la plupart des traces MMIO sont beaucoup plus grandes), nous avons trouvé :

YUY2
NV_PVIDEO.[0].FORMAT <- 0x00110200

YV12
NV_PVIDEO.[0].FORMAT <- 0x00110101
NV_PVIDEO+0x800 <- 0x00000000
NV_PVIDEO+0x808 <- 0x07fcffff
NV_PVIDEO+0x820 <- 0x07f70000

Nous avions donc une valeur différente écrite dans FORMAT, et trois registres inconnus. En cherchant dans la documentation et le code existants, il est apparu que le bit 0 du registre FORMAT nous était inconnu.

Nous avons donc essayé de faire marcher l'overlay YV12 dans Nouveau, tout d'abord en mettant simplement à 1 le bit 0 de FORMAT, et sans toucher aux trois registres inconnus. Résultat : pas de vidéo. Il y avait donc un effet, mais nous n'étions pas sûr que le bit 0 de FORMAT correspondait bien au bit "YV12".

Une lecture plus approfondie des MMioTraces nous a montré que ce qui était écrit dans les trois registres était en fait assez similaire à ce qui était écrit dans les registres qui servaient à configurer le tampon de données (indiquer son adresse et sa taille notamment). Nous avons pu deviner ce qui devait être écrit à cet endroit (il s'agissait en fait de la configuration du tampon de couleur, sachant que le tampon principal était utilisé pour les informations de luminance).

Finalement, nous avons fait marcher YV12 dans Nouveau, sans conversion en YUY2, ce qui représente une amélioration de performance des 25% attendus. MMioTrace nous a permis de découvrir comment la carte devait être programmée pour afficher des données YV12, ce qui n'était semble-t-il connu de personne en dehors de NVidia auparavant.

Cela a fini dans nv10_video_overlay.c, dans NV10PutOverlayImage:
/* Those are important only for planar formats (NV12) */
if ( uvoffset )
{
nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_BASE(buffer), 0);
nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_OFFSET_BUFF(buffer), uvoffset);
}

Il est intéressant de préciser que MMioTrace se contente d'enregistrer les opérations de lecture/écriture réalisées par le noyau - vous pouvez voir presque tout ce que le module noyau fait à la carte. Le désavantage évident étant que « presque tout » représente rapidement une grosse quantité de données :
plusieurs méga-octets, voire plusieurs dizaines, après quelques minutes de MMioTrace. Parcourir ces centaines de milliers de lignes pour trouver celles qui sont intéressantes peut être difficile et nécessite un peu d'expérience.

Nous avons utilisé MMioTrace pour comprendre le fonctionnement de l'overlay YV12, mais aussi pour une majeure partie du code d'initialisation de la carte et de configuration des modes - et il nous servira encore pour beaucoup de choses.

MMioTrace n'est pas limité à Nouveau, il peut tracer les opérations MMIO de n'importe lequel de vos modules noyau (binaires), ce qui permet d'effectuer de l'ingénierie inverse pour n'importe quel matériel.


== Développements actuels dans le domaine graphique sur Unix et leur influence sur Nouveau ==

Nous allons maintenant jeter un oeil sur le futur de l'accélération 3D sous GNU/linux. L'année 2007 a vu un grand nombre de changements majeurs apparaître dans la façon dont Linux et X11 gèrent la partie graphique.
Un grand nombre d'améliorations vont commencer à être utilisées : EXA pour l'accélération 2D, TTM pour la gestion de la mémoire, Gallium3D pour la 3D, la nouvelle interface DRI2... Tous ces changements nécessitent une adaptation des pilotes qui peut prendre du temps.

Avec l'arrivée des cartes graphiques programmables, le design actuel des pilotes graphiques Mesa commence à devenir inadapté. Celui-ci avait en effet été conçu pour des cartes basées sur des fonctions OpenGL fixes, c'est à dire possédant des circuits spécifiques à chaque partie du pipeline GL.
Le design pour ce type de cartes requiert un appel dans le pilote pour chaque nouvelle fonction fixe, ce qui devient vite complexe et oblige à une duplication de code importante entre les pilotes.

Un nouveau design de pilote, Gallium3D, tente de remédier à cela en simplifiant l'interface du pilote tout en maximisant le code partagé. Il est conçu pour fournir tout ce qui est nécessaire à OpenGL 3.0, mais également aux API DirectX ou OpenGL actuelles. Il doit également permettre une portabilité des pilotes sur les OS et plateformes majeurs. Il requiert des circuits graphiques programmables possédant au moins des « fragment shaders ».

Maintenant que nous savons pourquoi le design a changé, voyons l'architecture de Gallium3D. Celui-ci sépare le pilote DRI en 3 composantes : un traqueur d'états commun, une couche « winsys » dépendante de l'OS et un pilote spécifique à la 3D du matériel.

Le winsys est en charge de la partie 2D, de la plupart des tâches de gestion et des parties spécifiques à un OS, tandis que le pilote "matériel" gère la 3D. Chaque pilote doit implémenter la partie gestion matériel et le winsys. Lorsqu'un pilote est porté vers un autre OS, seule la partie winsys doit être réécrite.

La référence complète implémentée de façon logicielle est appelée softpipe. C'est un moteur de rendu logiciel qui permet de présenter les concepts derrière Gallium3D, comment les implémenter et qui agit comme un recours logiciel pour les fonctions que le matériel ne gère pas.

Un dernier composant du nouveau système graphique est le gestionnaire de mémoire TTM qui gère dans le noyau et de façon unifiée toute la mémoire accessible au GPU.
Auparavant, la gestion de la mémoire était séparée entre les pilotes X et utilisait surtout des allocations statiques. TTM a été conçu et implémenté au départ pour les circuits Intel et a dû être adapté pour le matériel NVidia et le design logiciel de Nouveau. La principale fonction, nécessaire pour la gestion des contextes matériels multiples des circuits NVidia, qui a été ajoutée est appelée fence classing.


== Statut actuel ==

Lorsque, l'année dernière, nous sommes passé de l'ingénierie inverse à l'écriture du pilote, on nous a demandé quand celui-ci serait prêt. Nos prédictions tablaient sur l'automne 2007 mais finalement, seule une partie du travail était finie.

À l'exception des NV5x, nous avons un pilote 2D relativement bon. Durant un temps, nous avons même envisagé l'idée de la sortie d'une version uniquement 2D du pilote, idée que nous avons finalement repoussée, l'interface noyau n'étant pas assez stable pour un support à long terme. En effet, lorsqu'un module (comme notre module DRM) est intégré dans le noyau Linux, ses interfaces doivent être par la suite conservées indéfiniment. Ce qui ne serait pas très approprié actuellement pour Nouveau, étant donné que les interfaces vont être amenées à évoluer avec l'arrivée du TTM et de la gestion des modes dans le noyau. Conserver les anciennes interfaces rendrait très complexe l'utilisation et le support des nouvelles.

Aujourd'hui, Nouveau est capable des fonctions suivantes :
Actuellement, Les NV5x sont le point faible de notre pilote : elles fonctionnent en 2D de la même façon qu'avec le pilote nv, mais la sauvegarde/restauration de l'état des terminaux virtuels (non-X) ne fonctionne pas.

Tout cela est bien beau mais je vous entends demander : « Et la 3D alors ? »

La réponse courte est simple : nous n'avons pas de 3D fonctionnelle.

La réponse longue est un peu plus nuancée :
Rien ne fonctionne sur NV5x et comme beaucoup de choses ont changé par rapport aux NV4x, pas mal d'ingénierie inverse va être nécessaire. Pour les autres cartes, nous avons les informations mais il y a encore beaucoup à comprendre et à réaliser avant d'avoir un pilote final.

Glxgears fonctionne sur NV1x, NV3x et NV4x mais c'est un prototype et il subsiste différents problèmes. Il faut noter que le travail sur le pilote DRI a cessé au profit de Gallium3D.

Un pilote Gallium3D plus ou moins fonctionnel existe mais avec encore de nombreux bogues et erreurs. Même si ça s'améliore quotidiennement pour les NV4x, on est encore loin de pouvoir jouer avec. Cela dit, Gallium3D lui même est toujours en cours de développement, il ne parait donc pas étonnant qu'il en soit de même pour notre pilote.

La gestion des modes fait actuellement l'objet d'un travail important d'amélioration par Maarten Maathuis et Stuart Bennett, ce qui à terme devrait amener une gestion de RandR1.2 (bi écran et autres) avec Nouveau.
Une fois terminé, tout comme d'autres pilotes, nous prévoyons de migrer la gestion des modes dans le noyau. Une API noyau a été définie dans ce but ( http://lkml.org/lkml/2007/5/17/342, http://lwn.net/Articles/218380/ et http://gitweb.freedesktop.org/?p=MESA/drm.git;a=shortlog;h=m(...) ). Elle ressemble à une version simplifiée de l'API Randr1.2, ce qui devrait rendre la migration assez simple.


Bon, et à quoi devons nous nous attendre ensuite ?

Ceci est seulement une approximation des objectifs à moyen terme :
Évidemment, si vous voulez plus de détails, parcourez notre Wiki, lisez les TiNDC ou rejoignez nous sur le canal IRC #nouveau sur freenode (archives disponibles ).

Pour ne pas déroger à la tradition, voici quelques captures d'écran, et commençons par le jeu des 7 différences.
Voici une capture du blob et de Nouveau qui représente le début du premier niveau de NeverBall :

Capture de Nouveau

Capture de NVidia (pilote binaire)

Ben Skeggs semble avoir noté quelques petites différences aussi, et après quelques semaines, a corrigé les rendus incorrects.

Et voilà ce à quoi ressemble OpenArena avec le pilote Nouveau Gallium3D de janvier 2008 :
Capture d'OpenArena

Il semble que les armes sont un peu trop sombres, mais à part ça, il n'y a pas de différences flagrantes.

Plus d'informations sur Gallium3D sur le site de Tungsten Graphics :
http://www.tungstengraphics.com/wiki/index.php/Gallium3D
http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007(...)


Bref, voilà où nous en somme aujourd'hui. Notre feuille de route montre que la prochaine étape importante sera Quake. Elle n'est pas trop loin pour les NV4x, un peu plus pour les autres cartes, d'autres problèmes étant sur le chemin.
Notre première estimation d'automne/hiver 2007 pour une première version n'était finalement pas si mauvaise si on ne regarde que la partie 2D ; même si nous avons du la repousser à cause de certaines décisions architecturales dont nous ne maîtrisons pas forcément tous les délais (TTM et Gallium notamment).
Nous pensons tout de même que ces décisions étaient bonnes et Nouveau sera l'un des pilotes les plus pérennes et les plus avancés technologiquement.

Pour terminer, je (KoalaBr) voudrais remercier Arthur Huillet, Ben Skeggs, David Airlie et Stephane Marchesin pour leur aide dans la rédaction de cet article. Ce fut réellement un vrai travail d'équipe !
Traduction réalisée par Mjules, avec l'aide de Stéphane Marchesin et Arthur Huillet.

Cette discussion est archivée, il n'est plus possible de laisser des commentaires.

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.

Neverball

Posté par Narishma Jahar () le 19/02/2008 à 16:36. (lien). Évalué à 6.

Les captures d'écran de Neverball sont inversées je crois.

Arg

Posté par Axel () le 19/02/2008 à 16:42. (lien). Évalué à 6.

Je crois que j'ai explosé mon quota de surf mensuel :/

Polémique

Posté par patrick_g (page perso, ) le 19/02/2008 à 16:46. (lien). Évalué à 10.

Remarquable dépêche, très détaillée et intéressante.

A noter que la parution de cet article dans le LWN de jeudi va être accompagnée d'un long commentaire de Jon Corbet sur l'utilité du projet Nouveau. Le titre est "Reverse engineering: more than NVIDIA deserves?" ce qu'on pourrait traduire par "L'ingéniérie inverse: Plus que ce que mérite NVidia ?".
Selon Jon il y a essentiellement trois acteurs sur le marché des cartes graphiques : Intel, AMD et NVidia.
Intel propose depuis toujours des pilotes libres et a commencé récemment à fournir aussi de la documentation sur ses cartes. Comme une équipe dédié existe chez Intel, l'aide de la communauté des développeurs du libre est réduite.
AMD a aussi choisi de basculer vers le libre et a fourni de la documentation sur ses cartes.
NVidia au contraire ne propose aucun code libre et aucune documentation. La seule chose qui est fournie est un gros blob binaire.
Le problème du projet Nouveau est que cela constitue une "aide" gratuite à la seule firme qui conserve sa mentalité ultra-propriétaire. Pourquoi aider ainsi notre ennemi alors que les deux autres firmes n'ont que peu d'aide de la communauté ?
Jon écrit : "NVIDIA, instead, is giving us nothing - and, in return, we are giving it an eight-person development team dedicated to the production of free drivers for its hardware (..) NVIDIA does not deserve a gift of this magnitude from the community".
Quand il n'y avait aucune autre solutions cela pouvait apparaitre acceptable de se lancer dans l'ingéniérie inverse du hardware fermé de NVidia. Maintenant que les concurrents de NVidia sont tournés vers le libre, que les gammes qu'ils couvrent sont complètes (entrée de gamme pour Intel et haut de gamme pour AMD) pourquoi aider ainsi NVidia ?
Il faut au contraire "punir" NVidia de sa non coopération : "So there will be no need to buy hardware from this particular vendor, and, since the alternatives will be well supported, every reason to buy from somebody else".

Bien entendu Jon admet que Nouveau est intéressant pour les possesseurs actuels de cartes NVidia. Il admet également que certaines personnes s'amusent à savoir comment marchent les cartes graphiques et à écrire des pilotes. Il n'y a pas de mal a être curieux et à écrire du code libre. Mais il faut réfléchir aux conséquences à long terme : "So, as a community, we cannot make a collective decision to stop this kind of development. But, as individual developers, we may occasionally want to give a moment's thought to the question of whether our activities are truly beneficial in the long run.".

A noter qu'il y a eu beaucoup de réactions à cet article de Jon Corbet et que beaucoup de gens sont en désaccord avec lui. Parmi eux il y a, hélas, ceux qui disent que NVidia écrit les meilleurs pilotes pour Linux : "instead of complaining about NVIDIA, we should be thanking them for releasing an excellent (yet unfortunately closed-source) driver".
Mais il y a aussi des arguments plus solides et de nombreuses personnes soutiennent que NVidia ouvrira a un moment ou à un autre ses pilotes. Quand les alternatives libres seront compétitives en terme de performances il n'y aura plus d'avantage comparatif à avoir un pilote fermé et la rationalité prévaudra chez les dirigeants d'NVidia. Dans l'intervalle Nouveau servirait à aider les infortunés libristes ayant acheté des cartes graphiques NVidia et le projet serait donc bénéfique.

Dans tous les cas l'article de Jon Corbet (et ses commentaires) est une lecture très intéressante et je vous le recommande (il ne sera accessible que jeudi prochain pour les non abonnés).