Saturday, September 07, 2019

272 sprite pixels / line.


Si faire une image sur DS c'est un peu comme monter une bibliothèque-étagère contre un mur, alors faire une image sur Super Nintendo, c'est pareil. Sauf que le toit est en pente, qu'il y a un conduit de cheminée qui dépasse, des poutres de toiture apparentes et une tablette d'appui de fenêtre dans le chemin.

Bref, il y a des contraintes à gogo et il faut tenir compte de toutes ces contraintes-là en même temps. Une qui m'a particulièrement perturbé, c'est la limite à 34x8 pixels de sprites par ligne horizontale en plus de la contrainte d'un maximum de 32 sprites par ligne (sur un total de 128 sprites, quand-même. ouf.)

En clair, la console a beau être capable de faire le rendu d'un sprite de 16x16 ou 32x32 pixels d'un coup, ça ne lui donne pas plus la possibilité d'utiliser les sprites pour faire une ligne de vagues couvrant tout l'écran (256 pixels) avec 8 sprites de 32x32. Enfin, si, mais vous n'aurez plus droit qu'à deux personnages sur la même ligne, et pas 24 autres sprites.

Je me suis donc mis à essayer de comprendre comment la structure du chip graphique de la Super Nintendo pouvait bien expliquer ça. L'idée de base, c'est que la console n'a qu'une bande passante limitée à sa mémoire graphique, tout juste suffisante pour aller chercher assez d'informations pour construire une ligne d'image sur le temps qu'une ligne de graphisme est tracée à l'écran par le canon à électrons. J'avais déjà appris que c'était vrai pour les décors -- c'est ce qui explique qu'on doive descendre à 4 couleurs par plans si on veut ajouter plus de plans -- reste à comprendre ce que ça implique pour les sprites.

Pour chaque pixel que le contrôleur du signal d'écran produit, il va falloir tester les sprites actifs et pour certains (peut-être chacun) d'entre-eux, il faudra regarder si le pixel correspondant est transparent ou opaque. Le premier pixel opaque dans l'ordre de priorité défini par le hardware gagne le match et les autres ne seront pas pris en compte. Ce genre de chose peut être réalisée efficacement avec un bus à collecteur ouvert et un circuit de contrôle des sorties de chaque unité "pixel pour le sprite S" dépendant du résultat des circuits précédents. Mais ça suppose qu'on ait, pendant toute cette phase de génération d'image, accès à l'ensemble des pixels de tous les sprites pour la ligne en cours.

La bande passante de la mémoire n'est pas suffisante pour aller regarder chacune de ces valeurs à chaque pixel, il faut donc supposer qu'il y a à l'intérieur du chip graphique un cache de 8 pixels de large (d'où le x8) pour chaque comparateur et que ce cache est rempli une et une seule fois lors du traîtement de la ligne.

Il me restait à comprendre comment ce genre de préparation est compatible avec des sprites dont on peut modifier la position en cours d'image. Et là, surprise: selon Upsilandre,

[...] Tu peux pas modifier la [Sprite Attributes Table] pendant l'affichage, ça veut dire pas de multiplexage software possible contrairement à la megadrive.

Le principe des sprites au raster c'est que les 34 patterns sont chargé en amont pendant le Hblank dans des registres internes. Ensuite c'est un jeu de priorité cablé dans le hardware qui va fait que tel pixel de tel registre aura la priorité sur les autres.

En arcade c'est mieux, t'as un (double) line buffer donc ils peuvent charger les pattern pendant toute la durée de la scanline précédente (et pas juste pendant le Hblank) c'est ce qui leur donne ces performances bien supérieur

J'aurais cru que la technique de multiplexage -- classique sur C64 ou NES et possible sur NDS -- était omniprésente sur console, et sur la 16-bit de Nintendo aussi. Visiblement non.

Et pour creuser un peu plus loin, les chiffres sont sur http://folk.uio.no/sigurdkn/snes/timing.txt. C'est un peu difficile d'en tirer un nombre d'instructions possibles par ligne retracée à l'écran, mais les chiffres annoncés me portent à croire que le 65xxx dont la Super NES est équipée garde une architecture interne très proche de celle du 6502, avec un bus unique entre les différentes unités internes et du "microcode" qui s'exécute à la fréquence de la master clock de la clock processeur mais qui peut nécessiter un nombre de cycles d'horloge variable (de 3 à 6) pour exécuter une instruction, ce qui donne entre 200 et 500 50 et 73 instructions par ligne retracée à l'écran.

On comprend mieux du coup les ruses de sioux du style "on ne va pas tester toutes les collisions à chaque images" qui régnaient en maître à l'époque..

No comments: