30. 8. 2013

Racing the Beam


Magických rock solid 60 fps synchrónnych so 60Hz refreshom LCD telky si určite želá každý hráč na konzolách tak dnes ako tomu bolo v dávnoveku na CRT TV. Na vykreslenie jedného z tých 60 frejmov má mašina iba 1/60 sekundy čo je cirka 17 milisekúnd /1000:60=16.666 ms/. To nie až taký problém, keď sa uspokojíte s horšou grafikou. Ak ju však chcete mať čo najlepšiu, padáte na najbližší celý násobok refreshu čo je pomer 2:1 a 30 fps. Nuž a 33.333 ms /1000:30fps/ už stačí aj na poslabšom HW na slušný vizuál. Ak by vám to predsa len nestačilo, tak idete na 15 fps /pomer 4:1/ a 66.666 ms - takto nám bežali bojové 3D scény v slávnej Final Fantasy 7. Square to vtedy ešte s hardvérom Psone príliš nevedel.

Skúsme to však ešte nejako našej šunke uľahčiť. Už keď sa jej nejako ten frame za 17, 33 či 66 milisekúnd podarí zo seba vypotiť a ten sa postupne po riadkoch vykresľuje na obrazovku čo robí GPU s boľným časom medzitým. Ráta ďalší frame. Niekde ho však musí uložiť a takto sme sa dostali ku dvom video bufferom /jeden je vykresľovaný, druhý sa v pozadi ešte len zapĺňa dátami/. Double buffering je roky štandardná fičúra a zabezpečuje aby refresh obrazovky mál stále k dispozicií čerstvé dáta a to načas. Ak nie, vykresľuje znovu starý frame. Ten nový si buď celý jeden cyklus počká /čo určite pocítite na horšom ovládaní hry a nejakom tom vizuálnom artefekte/, alebo nečakáte a vbehnete tam uprostred vykresľovanie, narušíte synchronizácia a dostanete roztrhnutie obrazu /minimálne na 2 polovice, malý posun hlavne pri točení pohľadu po horizontále/ tzv. tearing.

To bol povinný úvod. Teraz po vám chcem, aby ste si predstavili túto situáciu. Pamäť je príšerné drahá. Pracovná ram vašej mašiny má teda iba 128 bajtov /!!/, hry sú na 4KB kártridžoch a nemáte žiadnu vram. Nič, nada, zero. Ani pol bajtu, žiaden single-double-tripple buffering. Navyše máte iba 2 /player/ + 2 /missile/ +1 /ball/ HW sprajty a chce sa od vás aby ste naprogramovali hru, ktorá má more farieb, desiatky objektov a všetko sa to hýbe na tých 60fps. Ten systém sa volá ATARI VCS alias Atari 2600  a ide o pekelný stroj, ktorý sa preslávil jednak skvelými hrami, druhak komplexnosťou svojho programovania a tretiak práve technikou zvanou - racing the beam /download knihy, torrent/. Mimochodom 2600ka stála v 1977 /tiež štart filmovej série Star Wars/ skvelých 199 USD, čo dnes po započítaní inflácie robí presne 767 USD, dobrú chuť.

Ten lúč /beam/ totiž nie je nič iné ako elektronové delo, ktoré to pálilo do fosforového CRT tienidla. A to veru na nikoho nečeká. Ak má PS3 hry na jeden frame 33 ms pri 30 fps hre. Atari 2600 tie pixely so seba muselo chrliť v reálnom čase presne pod ruky elektronového lúča /z CPU registra via TIA rovno na obrazovku, zabudnite na 33ms na jeden frame/. Opakujem - nemáte vram. Je to šialené a chce to trochu inžinierského filipa ako na tom vôbec nejakú hru urobiť. Začneme tým, že ak CPU nerobí nič iné ako naháňa elektróny, kedy stihne napríklad ošetriť vstup z joysticka alebo ošetriť audio. Pozrite si ľavý obrázok nižšie /hra Pitfall, kt. technicky by nemala v tejto kvalite na 2600ke vlastne ani existovať/. Vidíte tam nejaké "biele" oblasti bez grafiky /V.blank, H.blank, Overscan/ čo je práve priestor, kde lúč nič nevykresľuje -  CPU mu nič neposiela a má teda "dosť času" práve na vyššie spomenuté operácie /časovanie však muselo byť presné na militakt/. A ideme ďalej.


Atari 2600 má tu vlastnosť, že jej grafická pipelajnu má doslova totálnu flexibilitu a per riadok /scanline/ vie meniť svoj grafický režim/paletu/manažment sprajtov. Príklad. Máme tu HW sprajt, ktorá ma defaultne v manuály napísané, že pri ňom môžte použiť iba jednu farbu /monochromatický panduľák/. Avšak Pitfall má postavičku Indiana Jonesa - farebnú /viď obrázok vyššie vpravo/. Je to dosiahnuté práve zmenou "grafického" režimu, palety farieb v každom riadku /scanline/ osobitne. Náš Indiana dokocna visí na elastickej liáne. Ako to dokázali ? Opäť rovnako. Jeden sprajt /typ - ball, pôvodne "ušitý" pre Ponga/ je multiplexovaný per riadok a roztiahnutý na pol obrazovky /elasticitu dosiahli opäť posunom o pixel, či dva v každom nasledúcom riadku/. Technicky ide o super primitívnu verziu akéhosi programovateľného pixel shadera /tieto techniky sa neskôr masívne používali aj na Amige 500, C64ke alebo Spectre/.

Teraz niečo ťažšie. Pacman. Všeobecný konsenzus hovorí, že hra saje oslí zadok. Ak ste rozmaznaný arkade verziou, tak táto pre 2600ku sa vám páčiť nebude /to blikanie sprajtov je spôsobené tvrdými HW limitmi pri ich vykresľovaní a nezvládnutím kódovania pre 2600ku/. My už však vieme, že 2600 zvládne iba 5 interaktívnych objektov. To nám stači akurát na "štyroch duchov" a jedného pacmana, kde je tu však miesto pre asi stovku tých malých sračiek, ktoré pacmana musí zožrať. Rieši sa to takto. Tie malé mrchy sú akože súčasťou playfieldu /bitmapa v pozadi/ a po zjedení každého sa herné plocha prekreslí celá nanovo, proste "nové" bitmap pozadie /duchovia su prekresľovaný rovnakým ghetto štýlom, nie v jednom frame naraz, ale jeden duch v prvom frejme, v druhom fejme druhý duch, hehe/. Neskoršie verzie pacmana - Ms. Pacman a hlavne PacManPlus už fungovali ako víno a bez blikania.

Ešte niečo ťažšie. Space Invaders. Animované, pohybujúce sa sprajty umiestnené v radoch vedľa a nad sebou. Ako na to. Máme k dispozicií stále iba 2 x player sprajt a aj jasné limity, koľko sprajtov vedľa seba môže byť na jednom riadku. Použijeme všetky techniky uvedené vyššie - sprite multiplexor a fakt, že už vykreslené sprajty ostanú na svojom mieste až do ďalšieho priebehu lúča. Takže horná rada enemákov je multiplexovaná a vykreslená /fire and forget/, lúč letí po riadkov ďalej, my o kus ďalej opäť multiplexuje nový sprajt, starý nám nezmizne /!!/ - prežije to až do ďalšieho cyklu a takto pod seba nasekáme aj stovku animovaných objektov /neskoršia homebrew verzia to vylepšila o kopu farieb/. Časom takto zvládnete aj paralaxné skrolovania ala amiga v hre Star Wars: The Empire Strikes Back alebo vkusné 3D s denným cyklom a nočným videním v hre Robot Tank. Dnes už nie je na Atari 2600 nič nemožné a prekonali sa aj najdivokejšie predstavy inžinierov atari v 1977.

---------------------------

Po pravde som veľmi podobný článok venoval 2600ke už pred piatimi rokmi ale k tejto téme ma opäť vrátil malý príspevok Timothy Lottesa /ex Nvidia, vynálezca FXAA antialiasing, teraz maká pre EPIC/, ktorý si práve na racing the beam tiež pred pár dňami spomenul. Timothy je veľkým advokátom tzv. programovania hier na konzolách /viď nižšie/, bez ohľadu na to aký výkonný PC HW mal v rukách. Prečo ? Odpoviem vám zdanlivo nezmyselne - lebo ani jedna z next gen konzol PS4/Xbone nebude používať DirectX API.

Poviete, hej hej, zadrž svoje kone. Je to však naozaj tak. PS4 GPU a Xbone GPU síce majú celý súbor vlastností-extenzií potrebných pre splnenie normy DirectX 11.2 /v skutočnosti idú oveľa ďalej/ ale DX API na nich nenájdete. Je príliš pomalé, nepoužiteľne pomalé. Xbone teda použije vlastné super custom riešenie, oveľa štíhlejšie a ušité na telo hardvéru s mnohými programátorskými skratkami a fintami, PS4 to isté v bledo modrom. A hovorím to preto, lebo len ťažko nájdete rýchlejší spôsob ako dostať pixel na obrazovku, než ako to robí práve Atari 2600 /rovno z CPU registra na display/, s menším počtom krokov sa to už proste urobiť nedá. A o tom vlastne hovorí Carmack, keď tvrdí, že PC hardvér v krabici od konzoly dvihne svoj výkon automaticky o 100%. Je to dané práve "hernými" ovládačmi a špeciálnym grafickým rozhraním, ktoré sa snažiť dostať čo najbližšie ku roku 1977. Stále platí - maximálna jednoduchosť a flexibilita = maximálny výkon a future proof potenciál. Aj preto Mark Cerny tvrdí, že PS4 dostalo toľko slobody pri programovaní /technicky aj voľnú ruku pri softvérovom renderingu alebo manuálnom riadeni fragment shadera, čo je dnes viacmenej tabu/ a tak nízky "low level" pristup ku hárdveru, že geniálni programátori z nej dostanú veci, ktoré aj on sám veľký guru a architekt PS4ky - považuje za nemožné. Ako pri tej Atari 2600.