Le 7 septembre 2026, nand2mario a présenté zSST, une implémentation SystemVerilog de la 3dfx Voodoo Graphics, aussi appelée SST-1. Le projet fait suite à un mois de travail sur z486_MiSTer et à l'envie d'explorer les cartes 3D apparues après la première moitié des années 1990. Need for Speed II SE en a fourni le point de départ, avec ses textures, son brouillard et sa fluidité.
void grDrawTriangle(const GrVertex *a, const GrVertex *b, const GrVertex *c);zSST est intégré au processeur z486 et aux périphériques PC dans z486 XL. L'ensemble forme un PC DOS doté d'une carte Voodoo dans la logique programmable d'une carte Xilinx KV260. Tomb Raider utilise son moteur 3dfx d'origine. zSST prend en charge les triangles préparés, le filtrage des textures, le mipmapping, les tests de profondeur et d'alpha, le brouillard, le blending, le dithering, l'accès au framebuffer et les changements de buffer. Les interfaces de préparation en virgule fixe et en virgule flottante sont prises en charge. Les essais matériels portent surtout sur Tomb Raider. La compatibilité générale et les générations Voodoo suivantes restent à développer.
Le processeur et le moteur de rendu fonctionnent à 100 MHz sur la KV260. La logique, les blocs DSP, la mémoire intégrée et la bande passante DDR de la carte suffisent au système complet. La DE10-Nano ne dispose pas de la place nécessaire pour cette extension graphique. La KV260 utilise sa DDR intégrée et ne requiert aucun module SDRAM externe.
L'implémentation s'appuie sur le code source Glide publié par 3dfx en 1999 et sur la spécification SST-1. 3dfx avait publié Glide avant que NVIDIA n'acquière ses actifs graphiques principaux en décembre 2000. Le code Glide conservé, la spécification SST-1, 86Box, les premiers travaux Voodoo de MAME et les traces de SpinalVoodoo ont fourni des références de comportement et des données de test. La spécification décrit les registres et les résultats attendus, sans révéler la structure exacte du circuit original.
L'accélérateur dispose de cinq registres de commande principaux. triangleCMD démarre un triangle préparé, ftriangleCMD passe par l'interface de préparation en virgule flottante, nopCMD vide le pipeline et peut réinitialiser les compteurs de statistiques, fastfillCMD efface un rectangle limité de couleur ou de profondeur, et swapbufferCMD change le buffer affiché immédiatement ou au retour vertical. D'autres registres contiennent les coordonnées, les gradients et l'état du rendu. Des zones mappées en mémoire servent aux transferts de textures et à l'accès direct au framebuffer.
L'appel Glide grDrawTriangle reçoit trois sommets après transformation de la géométrie, calcul de l'éclairage, clipping et projection par le processeur hôte. La SST-1 ne possède pas de moteur matériel de transformation et d'éclairage. Le rasterizer détermine les pixels couverts par le triangle et interpole les couleurs, la profondeur et les coordonnées de texture. L'unité de texture lit et filtre les texels. Le chemin framebuffer applique les tests de visibilité, le brouillard et le blending, puis écrit le résultat.
La Voodoo originale répartit ce travail entre le Frame Buffer Interface, ou FBI, et la Texture Mapping Unit, ou TMU. À 50 MHz, son débit annoncé atteint un pixel de sortie texturé et testé en profondeur par cycle, soit 50 millions de pixels par seconde. Plusieurs pixels occupent simultanément des étapes différentes. Un pixel traverse plusieurs étapes avant sa sortie. Une fois le pipeline rempli, il peut accepter un pixel par cycle lorsque la mémoire suit. Cette organisation a contribué aux jeux 3D texturés à 30 FPS ou davantage.
Le logiciel peut fournir des valeurs en virgule flottante, tandis que l'essentiel du rendu utilise des nombres en virgule fixe. Les formats internes sont 12.4 pour X et Y à l'écran, 12.12 pour le rouge, le vert, le bleu et l'alpha, 20.12 pour la profondeur Z, 14.18 pour S/W et T/W des textures, et 2.30 pour l'inverse de W. Les registres fvertex, fstart et les gradients flottants acceptent des valeurs IEEE simple précision. La SST-1 les convertit vers ces formats fixes. L'interpolation se réduit ensuite largement à des additions d'incréments précalculés.
Pour les textures corrigées en perspective, la TMU interpole S/W, T/W et 1/W, puis divise les deux premières valeurs par la troisième. Elle sélectionne un niveau de mipmap et applique un filtrage bilinéaire à quatre texels voisins. zSST utilise quatre étapes en entrée pour les calculs de perspective et de niveau de détail. La génération d'adresses, l'accès au cache, le décodage des formats et la combinaison des textures prennent en charge les textures indexées par palette et les textures codées en NCC.
Le chemin de pixels du FBI comprend six étapes enregistrées. F0 sélectionne les sources, vérifie la chroma key et prépare les valeurs Z/W. F1 applique les fonctions de combinaison de couleur et d'alpha. F2a effectue les tests alpha et profondeur et recherche le facteur de brouillard. F2b applique le brouillard. F3 reconstruit la couleur de destination et réalise le blending alpha. F4 convertit vers la précision du framebuffer, applique le dithering et les masques d'écriture. Ce découpage respecte la fréquence visée par le FPGA tout en conservant un débit d'un pixel par cycle.
L'accès mémoire a représenté la principale difficulté. La Voodoo originale donne au FBI et à la TMU des chemins mémoire séparés de 64 bits. L'interleaving des textures sur quatre banques utilise la parité paire ou impaire de la colonne et de la ligne. Chaque fenêtre de 2x2 texels atteint ainsi les quatre banques en parallèle. Le FBI utilise une organisation comparable pour les données de couleur et de profondeur ou d'alpha. Son débit maximal atteint un pixel rendu par cycle et deux pixels par cycle pour les effacements. À 50 MHz, chaque chemin de 64 bits offre théoriquement 400 MB/s, soit 800 MB/s au total. Les deux chemins restent affectés à leurs tâches respectives.
Sur la KV260, la DDR partagée est accessible via des ports AXI. Linux, le PC FPGA et la sortie d'affichage se disputent cette mémoire. Un port de 128 bits à 100 MHz offre théoriquement 1,6 GB/s. Avec une seule requête en attente, les mesures donnent 1 370 MiB/s pour une lecture de 4 KiB et 189 MiB/s pour 64 octets. Les premières données arrivent généralement après environ 280 ns, soit près de 28 cycles à 100 MHz. Certains accès prennent plus de temps.
zSST possède un cache de textures de 8 KiB avec des lignes de 64 octets. Huit chargements de lignes peuvent rester en attente. Une file de rejeu conserve les échantillons dont les données manquent. Un reorder buffer de 64 entrées restitue les résultats dans leur ordre initial. Le chemin framebuffer utilise des caches séparés de 4 KiB pour la couleur et la profondeur ou l'alpha. Des write combiners regroupent des mises à jour adjacentes de 16 bits dans des requêtes de 128 bits. Le forwarding conserve les dépendances lorsqu'une opération de profondeur ou de blending doit lire une valeur modifiée par un pixel précédent. Le FBI et la TMU partagent le port AXI HP2 du moteur. Le PC utilise HP0 et l'affichage HP3.
Les tests de simulation modélisent le timing DDR, la TMU, le FBI, l'arbitrage partagé et l'interface d'entrée. Les lectures arrivent après au moins 26 cycles, les écritures sont limitées, et les tests du moteur complet autorisent 32 lectures en attente. À 100 MHz, zSST atteint 78,5 MPix/s pour les triangles texturés et 72,8 MPix/s avec tests de profondeur et blending. Les estimations publiées pour la Voodoo 1 à 50 MHz donnent 43 et 37 MPix/s pour des groupes de fonctions comparables. Les charges diffèrent, donc ces chiffres indiquent une plage approximative et ne mesurent pas un gain de vitesse.
Sur la carte, le niveau 2 de Tomb Raider a produit 237 changements de buffer affiché en environ 20 secondes, soit environ 12 par seconde. La mesure compte les changements de buffer et n'utilise pas de compteur FPS du moteur. Les premiers résultats désignent le processeur comme limite principale. La concurrence sur la DDR peut aussi intervenir. Le z486 XL à 100 MHz atteint 38,5 FPS dans Doom avec le niveau de détail maximal et 8,1 FPS dans Quake 1.06. Ces valeurs sont environ 20 % supérieures à celles de la version DE10-Nano à 85 MHz. Le gain est d'environ 23 % pour Doom et 19 % pour Quake. Un cache L2 write-back de 512 KiB en UltraRAM aide le processeur à exploiter la DDR.
Dans la version intégrée XCK26, zSST utilise environ 29 500 LUT, 28 100 bascules, 14 blocs RAMB36, 8 blocs RAMB18 et 97 tranches DSP. Le système PC et graphique atteint le timing à 100 MHz. zSST et z486 XL sont disponibles en open source. La version z486_XL_20260906 de z486 XL fournit le support Linux et l'application nécessaires au démarrage d'images disque DOS sur une KV260. Le projet remercie SpinalVoodoo pour les traces Glide et les captures de référence, 86Box pour ses références d'implémentation et Fabien Sanglard pour son analyse de la mémoire de la Voodoo 1.




Commentaires
Pas encore de commentaire — écris le premier.
Lance la discussion
Pas de compte ni de mot de passe — saisis simplement ton adresse e-mail et nous t’envoyons un lien de connexion à usage unique. Première visite ? Tout se met en place automatiquement.
Ton évaluation sera appliquée automatiquement après ta connexion.
Vérifie ta boîte mail
Nous avons envoyé un lien de connexion à …. Ouvre-le sur cet appareil — cet onglet te connectera automatiquement.
Rien reçu ? Vérifiez le dossier spam — et marquez le message « Non spam » pour qu'il arrive directement la prochaine fois.