Co je vlastně v grafické paměti?
Kapitoly článků
Když jsme už zabrousili specificky ke kapacitě VRAM, byla by škoda nepodívat se, jaká data vlastně konzumují grafickou paměť. Největší porci většinou zabírají textury (ty jsou pro každou hru odlišné) a operační buffery. Ty jsou obvykle určené rozlišením, nastavením anti-aliasingu a částečně enginem hry (podstatné je jen, zda využívá multiple render targets):
Obvykle se využívají 3 operační buffery:
- z-buffer (hloubka scény), bývá 32bit per pixel
- frame-buffer back (též zvaný back-buffer) - prostor, do kterého se vykresluje, jeho barevná hloubka nejčastěji odpovídá 32bit per pixel (tedy RGBA 8-8-8-8), případně 64bit per pixel (používá se pro FP16 HDR a podobné efekty, tedy situace, kdy se s vykresleným obrazem ještě dále pracuje, odpovídá RGBA 16-16-16-16)
- frame buffer front - prostor, který obsahuje už výsledný poskládaný obraz (provedený MSAA resolve, blending atp.). Tento buffer slouží už jen k ukládání obrazu, který půjde na monitor, takže obvykle nebývá v HDR formátech, ani neobsahuje alpha kanál. V praxi se používá obvykle RGB 8-8-8, tedy 24bit per pixel. Pokud má grafická karta (aktivovaný) 10bit výstup, pak to může být RGB 10-10-10, tedy 30bit per pixel.
Pokud bychom hráli hru při rozlišení 1920×1200 s MSAA 8×, pak budeme pro operační buffery potřebovat:
- z-buffer: 1920 × 1200 × 8 (MSAA) × 32 (bit) = 589 824 000 bitů = 70,3 MB
- back buffer při 32bit barevné hloubce zabírá stejný objem paměti, tedy 70,3MB (pokud by byl ve formátu FP16, tedy 64bit per pixel, spotřeboval by 1920 × 1200 × 8 × 64 = 140,6 MB)
- front buffer = 1920 × 1200 × 24 (bit - bez alpha kanálu) = 6,6 MB
- celkový potřebný prostor: 70,3 + 70,3 + 6,6 = 147,2 MB
Některé hry (obvykle ty, které vycházejí z Unreal Enginu 3), používají tzv. multiple render targets, což si můžeme pro naší potřebu vysvětlit jako použití několika back-bufferů. Tím samozřejmě rostou požadavky na paměť a ve výpočtu to zohledníme vynásobením kapacity back-buffer počtem render targets (například dvěma).
Trochu matoucí může být anti-aliasing. Výrobci ve specifikacích grafických čipů často uvádějí kompresní poměr pro MSAA. To ale není komprese ve smyslu algoritmů jakými jsou ZIP nebo RAR, ale spočívá v prostém vynechání duplicitních dat. Např. MSAA 8× používá 8 vzorků na pixel. Pokud jde o pixel, který se ve scéně nenachází na hraně polygonu (a tudíž nebude vyhlazovaný), jsou hodnoty všech osmi MSAA vzorků identické a stačí tedy uložit jednu - takový přístup je nazýván kompresí 8:1.
Tím je sice ušetřena značná část přenosové kapacity sběrnice, ale grafickou paměť je přesto třeba zaalokovat v plném rozsahu. Před začátkem renderingu scény totiž není jasné, které pixely budou ležet na hranách polygonů a které ne (to znamená na kolika pixelech bude provedeno vyhlazení a na kolika ne) a kolik dat tedy bude třeba uložit. Proto musí být alokována paměť v plném rozsahu, který může být teoreticky (v teoreticky nejnáročnější situaci) potřeba, byť pravděpodobně nebude zcela využit.
Pro řešení takového plýtvání (které je tím větší, čím vyšší režim MSAA použijeme) byly vyvinuty úspornější formy anti-aliasingu: Nvidia CSAA a ATI/AMD EQAA. Obě jsou do značené míry obdobné a namísto některých MSAA vzorků používají vykrývací vzorky, jejichž nároky na kapacitu paměti jsou výrazně nižší. Při kombinaci s MSAA 8× zabírá každý vykrývací vzorek jen 4 bity na pixel. Pokud bychom hráli hru s anti-aliasingem 16×, který by kombinoval MSAA 8× + dalších 8 vykrývacích vzorků, vzrostly by požadavky na paměť (oproti samotnému MSAA 8×) jen o: 1920 × 1200 × 8 (nastavená hodnota MSAA) × 4 (počet bitů na vykrývací vzorek) = 8,8 MB.