:

Szerző: Bodnár Ádám

2000. november 10. 14:39

A Z-puffer és megoldások a sávszélesség- problémára

A modern videokártyák egyik legnagyobb problémája a szűkös memóriasávszélesség. Cikkünkben megpróbáljuk bemutatni a probléma okait és két lehetséges megoldást is. Az egyikük a PowerVR KYRO által is használt tile based deferred rendering módszer, a másik az ATi által bevezetett HyperZ eljárás.

Bizonyára vannak olvasóink, akik nem ásták bele magukat a 3D grafika világába. Ám azt hiszem a videokártyák piacán végbement robbanás őket sem hagyta érintetlenül. Akik rendszeresen nyomon követik a videokártyákkal foglalkozó rovataink híreit és olvassák Eg barátom "Górcső" cikkeit, azok bizonyára tudják, hogy a modern videokártyák egyik legnagyobb problémája a szűkös memóriasávszélesség. Cikkünkben megpróbáljuk bemutatni a probléma okait és két lehetséges megoldást is.

Az egyikük a PowerVR kártyákból ismert tile-based deferred rendering módszer, a másik az ATi által a Radeon-ban alkalmazott HyperZ eljárás, vagy inkább eljárásgyűjtemény. Ám ahhoz, hogy ezen módszerek lényegét megértsük, szükség van a jelenleg általánosan használt leképezési modell ismeretére is. Lássuk először ezt.

Egy három dimenziós jelenet gyakorlatilag nem más, mint poligonok összessége. Az általános gyakorlat szerint a modellek a létező legegyszerűbb poligonokból, azaz háromszögekből épülnek fel. Először az objektumokat a processzor vagy a videochip geometriai motorja a megfelelő mértékben átméretezi, eltolja és elforgatja, hogy létrejöjjön az általunk kívánt "színpadkép". A 3D jelenet ebben a pillanatban a program által létrehozott virtuális világban létezik. Ezt a teret (modellezési tér) a világ-koordinátarendszer határozza meg.

Ahhoz, hogy erről a térről kép készülhessen, el kell helyezzünk benne egy szemet, vagyis kamerát, amin keresztül a beállított jelenet lefényképzehető. Ennek során az objektumokat felépítő háromszögek csúcspontjainak koordinátáit transzformálnunk kell a kamera koordinátarendszerébe. A látómezőn kívül eső háromszögeket nem szükséges kiszámítani, így ezek "elvesznek", a motor levágja őket (clipping). Amennyiben használunk vertex megvilágítást, a csúcspontokhoz fényességértékek is rendelhetők (lighting).

A következő mozzanat az úgynevezett triangle setup. Ebben a fázisban a háromszögek csúcspontjainak fényességértékei alapján lineáris interpolációval meghatározzuk minden egyes pont fényességértékét. Majd a 3D jelenet pontjait megfeleltetjük a monitoron látható 2D kép pontjainak, azaz transzformáljuk a képtérbe.

[oldal:A Z-Buffer és a sávszélesség kapcsolata]

Ennek a folyamatnak a végén tulajdonképpen a jelenet Gouraud-árnyékolt változatát kapjuk. A képpontok mélységi adatai (azaz a Z koordináták) az úgynevezett Z-pufferbe kerülnek, ami egy külön terület a grafikus memóriában, és amelynek óriási szerepe van abban, hogy a mai videokártyák sávszélesség-gondokkal küzdenek.

A hagyományos architektúrákban most következik a renderelés. A renderelő motor sorra veszi minden egyes háromszög minden egyes pontját, és a megfelelő textúrákban hozzájuk rendelt színekkel színezi ki őket, majd ha van, jöhet a köd, füst, stb. Ha a motor végzett a szín kiszámításával, a pont Z-, azaz mélységi koordinátája alapján Z-tesztet végez, aminek segítségével megállapítható, hogy az elkészült képen a kiszámított pixel látható lesz-e, vagy egy másik pont eltakarja. Ha a frissen kiszínezett pont látható, akkor bekerül a frame bufferbe, ami tulajdonképpen a monitoron látható kép vetülete a grafikus memóriában. Ha képpontunk takarásban van, a motor egyszerűen eldobja és veszi az aktuális háromszög következő pontját, amelyen az ebben a bekezdésben leírt műveletsort hajtja végre.

Ez teljesen logikus, nem? Nos, a fent leírt módszer akkor lenne ideális, ha biztosak lehetünk benne, hogy nem lép fel "overdraw" jelenség, azaz a kiszínezett képpontok nem lesznek takarásban és egyiküket sem kell eldobni. Ugyanis ekkor a videochip által elvégzett munka kárbavész, ráadásul az összes pixelhez be kell tölteni a chipbe a megfelelő textúraadatokat - és később, a Z-tesztnél derül ki, hogy hiába.

Az igazság az, hogy egy olyan játékban, mint például a mindenki által ismert Quake 3 Arena, az "overdraw" három-négyszeres, azaz a videochip sokkal több pixelt renderel le, mint amennyi valójában a képen látszani fog. Ez azt jelenti, hogy a szükséges adatmozgás többszöröse zajlik a videochip és a grafikus memória között. A felbontás növelésével természetesen az elvégzendő munka és az adatmennyiség is nő, főleg akkor ha bilineáris vagy trilineáris szűrést alkalmazunk, ahol az adott pixel színét a környező 4 illetve 8 pixel színe is alakítja. Mindezekből látható, hogy a hagyoményos renderelési metódus elég pazarlóan bánik a memóriasávszélességgel.

[oldal:Az ATi HyperZ]

Az ATi által a Radeon chipben bemutatott HyperZ eljárás, ami valójában több apró trükkből áll, többféle módon igyekszik spórolni a memóriasávszélességgel. Az ATi Radeon videochip tartalmaz némi memóriát, amely egyfajta belső Z-pufferként funkcionál. Ennek a memóriaterületnek az elérése természetesen nagyságrendekkel nagyobb, mint a külső memóriáé, ami a kártyán található.

Nagyon fontos tudni, hogy a HyperZ effektek teljesen hardveresen valósulnak meg és nem függenek API-tól (DirectX, OpenGL, stb.) és operációs rendszertől sem. Mindössze drivertámogatás szükséges az eljárások használatához.

Az első és talán legfontosabb eljárás a HyperZ esetében a Z-puffer tömörítése. Erre egy változó hatékonyságú, veszteség nélküli eljárást alkalmaznak. A Z-puffert 8- és 64-pixeles blokkokra bontják, ezeket a blokkokat az eredeti méretük felére vagy akár negyedére is össze lehet tömöríteni. Ha szükség van valamelyik blokk tartalmára, a kitömörítés a chipben található belső Z-pufferbe történik.

A Z-puffer műveletekhez szükséges sávszélesség csökkentésén kívül ez az eljárás a Z-puffer helyigényét is csökkenti. Azaz a grafikus memóriában, ahol a külső (tömörített!) Z-puffer található, például sokkal több textúra férhet el. Miután a Z-értékek redundánsak is lehetnek, a tömörítés mértéke nem feltétlen felel meg a megtakarított memóriasávszélességnek.

[oldal:Az ATi HyperZ - második rész]

A következő trükk a "Fast Z-Buffer clear" nevet kapta. Minden egyes teljes kép elkészítése után, de még a következő kép elkészítése előtt szükség van a Z-puffer törlésére, amit eddig úgy oldottak meg, hogy egyszerűen feltöltötték nullákkal. A tömörített Z-puffernek és a belső Z-puffernek köszönhetően ez a hagyományos eljárás által igényelt idő töredéke alatt zajlik le.

Fentebb már szóltunk arról, hogy a Z-puffer blokkokra van osztva. A chip nem írja felül nullákkal a Z-puffer minden elemét, hanem a blokkok szépen sorjában egyszerűen töröltté lesznek nyilvánítva, kapnak egy címkét. Amikor a kitömörítésnél ez a törlésre utaló címke megjelenik, a chip a belső Z-puffert feltölti nullákkal. Tehát a "Fast Z-Buffer clear" egyrészr sokkal gyorsabban megy végbe, mint a hagyományos törlés, másrészt takarékosan bánik a sokat emlegetett memóriasávszélességgel is.

Tegyük fel, hogy 1024x768 pixeles felbontásban 32 bites színmélységben játszunk mondjuk a Quake 3-mal. Az akció mondjuk 30 fps-el jelenik meg a monitoron. Ez azt jelenti, hogy másodpercenként 1024x768x(32/8)x30~94 MByte sávszélesség szükséges csak a Z-puffer törléséhez. Ráadásul mivel a törlés utáni első Z-teszt esetén a chip tudja, hogy a Z-értéket mivel kell összehasonlítani (0), nincs szükség a Z-puffer betöltésére sem. Ezzel a megtakarított sávszélesség a kétszeresére, azaz másodpercenkénti 188 MByte-ra ugrik. 1600x1200 pixeles felbontás esetén a megtakarítás már 460 MByte/sec. (A példánkban a Fast Z clear eljárás által igényelt sávszélességet azért nem vontuk le a megtakarított sávszélességből, mert egyszerűen elhanyagolható).

A HyperZ még tartogat egy eljárást, amit "Hierarchial Z" néven ismerünk. Fontos azonban tudni, hogy ez alapértelmezés szerint ki van kapcsolva. A Hierarchial Z nem más, mint egy csökkentett felbontású Z-puffer, aminek segítségével a korábban említett 8 és 64 pixeles blokkok pixelein egyszerre végezhető el a Z-teszt. Sajnos a Hierarchial Z eljárás pontos menetéről az ATi nem hajlandó túl sokat elárulni, így sajnos - részletes információk hiányában - mi sem tudunk többet írni erről.

[oldal:A tile-based deferred rendering]

A PowerVR videochipekről leginkább az egyre népszerűbb KYRO révén lehet hallani manapság. Ezek a chipek a tile based deferred rendering eljáráson alapulnak. Lássuk, hogy működik ez!

A kép kiszámításának menete a triangle setup-ig bezárólag ugyanúgy zajlik, mint azt a hagyományos leképezési eljárás során ismertettük. Ám ezután a képet apró pixelblokkokra, azaz mozaikokra (tile) osztja fel a chip. A motor sorra veszi a mozaikokat, és meghatározza, hogy mely háromszögek vannak az adott mozaikban részben vagy egészben. Majd ezeket a háromszögeket mélység szerint egymás mögé állítja (depth sorting). Ha ezzel végzett, végigfut a mozaik pontjain és megvizsgálja, hogy mely képpont melyik háromszöghöz tartozik, és az adott képpontot a háromszöghöz rendelt textúra megfelelő színével kiszínezi.

Látható, hogy a háromszögek mélység szerinti csoportosításával kiküszöbölhető az overdraw jelenség, hiszen a renderelésnél már csak a látható pixelek kerülnek sorra. Ha a mozaik összes pixelének renderelése befejeződött, a pixeltömb bekerül a frame bufferbe.

Ennek a módszernek két előnye van. Az első, hogy teljesen kiküszöböli az overdraw jelenséget, azaz nincsenek feleslegesen renderelt majd eldobott pixelek. A másik előny, hogyha a mozaikot akkorára választjuk, hogy a Z-puffer elférjen a videochipbe épített aprócska cachememóriában, nem szükséges a chip és a grafikus memória közötti lassú adatbuszt olyan gyakran igénybe venni. Ez tovább csökkenti a szükséges memóriaszávszélességet. Ezért képes a KYRO 115 MHz-es SDR SDRAM-mal bizonyos esetekben akár a GeForce 2 GTS sebességét is hozni.

Sajnos ennek a módszernek is vannak hátrányai. Egyrészt a depth sorting eljárás nagy bonyolultságú chipet kíván, sok alkatrésszel, ami a magméretnél és az elérhető legnagyobb órajelnél visszaüt. Másrészt a poligonszám növelésével a depth sorting nagyon sok időt vesz igénybe. És mivel a programozók - főként a T&L adta lehetőségeket kihasználva - egyre több és több poligont mozgató játékokat terveznek, eléggé kétséges a technológia távoli jövője.

Mi mindenesetre nem kívánunk pálcát törni egyik lehetséges megoldás felett sem. Igyekeztünk legjobb tudásunk szerint bemutatni ezeket az eljárásokat, és olvasóinkhoz hasonlóan kíváncsian várjuk, vajon mit hoz a távoli jövő. Az mindenképpen bizonyos, hogy az elkövetkező videochipek (NVIDIA NV20, 3dfx GP1, stb.) már tartalmaznak ilyen vagy hasonló elvű sávszélesség-igény csökkentő eljárásokat. Ám hogy pontosan milyeneket, és milyen lesz ezeknek a hatásfoka, azt egyelőre nehéz lenne megmondani. Az biztos, hogy ha eljutnak hozzánk ezek a chipek, igyekszünk beszámolni a bennük található érdekességekről. Addig is jó játékot mindenkinek!

November 25-26-án 6 alkalmas K8s security és 10 alkalmas, a Go és a cloud native szoftverfejlesztés alapjaiba bevezető képzéseket indítunk. Az élő képzések órái utólag is visszanézhetők, és munkaidő végén kezdődnek.

a címlapról