Gainward
Grafická pipeline II: DirectX
V minulém díle naší mini-série o grafické pipeline jsme si představili počítačovou hru a její herní smyčku, která za pomoci volání 3D API generovala Draw Calls. Dnes na tento článek plynule navážeme a podíváme se, co se s těmito příkazy v 3D API děje dále, konkrétně tedy v DirectX.
gpureport.cz  Pavel Šantrůček  24.06.2016

OBSAH:
1. Úvod          
4. DirectX 12          
2. DirectX: Runtime, User Mode Driver a Context Queue          
5. Výhody a nevýhody DirectX 12          
3. DirectX: Sheduler a Kernel Mode Driver          
 

Microsoft DirectX

V dnešní době můžeme využít hned několika 3D API od různých výrobců. Nicméně, ať už se jedná o DirectX, OpenGL, Mantle, Vulkan či Metal, jejich účel je vždy stejný - přenést příkazy k vykreslení z aplikace (počítačové hry) do grafické karty ve formě, které daná grafická karta rozumí a může tak tyto příkazy vykonat.

Doma se u svých herních PC dozajista asi nejčastěji setkáte s 3D API společnosti Microsoft s názvem DirectX, které běží pod operačním systémem Windows. Poslední verze DirectX nese označení DirectX 12. Toto nejnovější DirectX bylo inspirováno 3D API Mantle od společnosti AMD a přináší do světa 3D opravdu mnoho nového. Abychom ale pochopili, jak revolučním API DirectX 12 opravdu je a co všechno se změnilo, musíme se nejdříve podívat na to, jak vše fungovalo do jeho příchodu. Takže pojďme do toho a podívejme se, jak vypadá diagram (pipeline) DirectX.

 

DirectX pipeline

 

Úseky, které jsou na obrázku vyznačené červenou a modrou barvou představují pipeline DirectX. API DirectX se totiž neskládá pouze s vlastních souborů a knihoven, ale část funkčních knihoven do DirectX musí dodat také výrobce grafického čipu formou ovladače (Driver). Proč tomu tak je a musí být, uvidíte hnedle. My nyní půjdeme pěkně po směru, kterým nám ukazují šipky v našem diagramu, budeme si představovat jednotlivé zastávky (Stage) DirectX a popisovat, co se v konkrétní zastávce děje.

Direct3D Runtime

Direct3D Runtime je první zastávkou v DirectX pipeline. Po zavolání vykreslovací funkce API v aplikaci se nám Draw Calls dostávají nejprve právě sem. V této zastávce jsou Draw Calls shromažďovány, nějakým způsobem validovány (základní kontrola chyb) a mezi jednotlivými Draw Calls vyhledávány nějaké souvislosti. Pokud například se zde objeví několik Draw Calls, které využívají stejné zdroje (například textury, shadery atd.) můžou se tyto Draw Calls sloučit do jediného. Vždy je totiž lepší, pokud potrubím „cestuje“ méně Draw Calls, nežli mnoho Draw Calls s opakujícími se odkazy na zdroje, které pak ve výsledku zahlcují pipeline mnohem více. Tomuto procesu se říká Draw Calls Batching a pokud je práce dokončena, takto upravené Draw Calls jsou odeslány do další zastávky s názvem User Mode Driver.

User Mode Driver (UMD)

User Mode Driver je jednou z nejdůležitějších zastávek DirectX a také se v ní děje asi to nejpodstatnější. User Mode Driver je knihovna, kterou dodává výrobce grafického čipu se svými ovladači a její hlavní úlohou je vypořádat se s rozdílnou kompatibilitou grafických karet.

Knihovna UMD pracuje ve stejném adresném prostoru jako aplikace, která DirectX využívá. Pokud například budete hrát na svém PC dvě hry současně, pak každá hra bude mít k dispozici vlastní instanci této knihovny, a pokud v UMD dojde k nějaké chybě (což se může lehce stát), „nezhroutí“ se vám celý operační systém, ale bude ukončena pouze ta hra, která danou instanci UMD využívala.

A jak že se vlastně UMD vypořádává s rozdílnou kompatibilitou GPU?

Právě zde se Draw Calls převádí do příkazů ve formátu, kterému konkrétní grafická karta rozumí a se kterými může nativně pracovat, tedy do jakýchsi příkazových dávek nazvaných Command Buffers (někdy jsou označovány také jako Display List, nebo později DMA Buffer). Stejně tak i shadery jsou zde kompilovány (překládány) do strojového kódu, který pak může být nativně spuštěn na výpočetních jednotkách konkrétní grafické karty. Součástí každého UMD tedy musí být ten správný kompilátor pro ten který typ grafické karty. Během kompilace shaderů jsou prováděny také různé optimalizace kódu a nejen to.

Valná většina optimalizací her za pomoci ovladače je prováděna také právě v UMD. Pokud se například jedná o nějakou známou či populární hru, kdy výrobce grafického čipu má velký zájem na tom, aby tato hra běžela na jeho hardware (GPU) s dobrým výkonem, dají se zde provádět také takové činnosti jako rekompilace a úprava, či dokonce kompletní náhrada shaderů. Pokud například nějaký shader, který vytvářel vývojář hry, není optimálně napsán pro danou architekturu GPU, pak v UMD mohou být tyto nevýkonné shadery vývojáře nahrazeny (pro danou architekturu GPU) výhodnější verzí shaderu, kterou si výrobce čipu napsal sám a dodal v ovladačích.

UMD je v neposlední řadě také zodpovědný za novou alokaci zdrojů (třeba textury) v grafické paměti GPU. Pokud například potřebuje nějaký příkaz v Command Bufferu později na GPU pracovat třeba s texturou, pak také tuto texturu musí mít k dispozici ve VRAM grafické karty. UMD tedy texturu alokuje ve VRAM a adresu tohoto umístění zapíše do příslušného Command Bufferu, aby příkaz při jeho pozdější exekuci věděl, kde konkrétně se tato textura ve VRAM nachází (ono je to trochu složitější, ale nám to takhle bude stačit).

Teoreticky vzato, po ukončení práce User Mode Driver máme prakticky vše potřebné hotovo a mohli bychom Command Buffery klidně rovnou poslat ke zpracování na grafickou kartu. Bohužel ale u předchůdců DirectX 12 (a WDDM 2.0) to ještě nejde a tak musíme naše Command Buffery poslat hezky zpět z UMD zase do Dirext3d Runtime, který je rovnou přesměruje do zastávky jménem Context Queue.

Context Queue

Context Queue není nic jiného nežli prachobyčejný zásobník našich Command Bufferů, které tam jsou připraveny k odeslání na zpracování grafickou kartou. Hlavním účelem tohoto zásobníku je zajištění paralelní práce mezi CPU/GPU a absorbovat také nepravidelnost dodávek Draw Calls z herní smyčky aplikace do API. V případě, že z nějakého důvodu aplikace přestane na čas dodávat Draw Calls do API, zbytek pipeline se nezastaví, ale čerpá Command Buffery dále právě z tohoto zásobníku.

Context Queue je někdy nazývána také jako Flip Queue, nebo také Pre-render Frame Queue a její kapacita je maximálně 3 snímky (Command Buffery pro 3 snímky). Velikost kapacity Context Queue ve hře může nastavit sám herní vývojář, ale častokrát je to také volitelná položka v ovladačích grafických karet. Obecně platí, že tato hodnota uvádí, kolik snímků může herní smyčka pro GPU dopředu připravit. Pokud by tato hodnota byla rovna 0, herní smyčka by se po odeslání snímku na GPU zastavila a musela by čekat, dokud ho grafická karta nevykreslí na monitor. Teprve po jeho vykreslení by mohla smyčka zahájit práce na přípravě snímku dalšího. Žádná paralelní činnost mezi CPU a GPU by se tedy nekonala.

Ačkoliv se může zdát, že čím více snímků budeme v této frontě mít, tím lépe a hladší rendering, věřte ale, že tomu tak není. Každý snímek, který putuje v pipeline navíc s sebou přináší také vyšší Lag (zpoždění), ale o tom až zas někdy jindy. V každém případě zásobník Context Queue tedy máme za sebou a můžeme jít dále, do další zastávky naší DirectX pipeline.

         
Předchozí kapitola   Další kapitola
         

SPONSORS & PARTNERS

Asus  Alza  MSI  Gigabyte
AMD  Sapphire  Gainward  Nvidia

Copyright (c) 2024 InfoTrade Powered by ASP.NET & MS SQL Server