Hirdetés

Képjavítási lehetőségek az MPC-HC-ben

Avagy shaderek használata és a tapasztalatok

Bevezetés

Bevezetés

Az MPC-HC népszerűsége töretlen, köszönhetően a lelkes fejlesztőknek, akik máig megtartották a minőséget és a fejlődést. A videokártyák pixel shader egységeit már rég befogja a program különböző funkciókhoz kötődve, de jelen írás fő fókuszpontja a shaderek kihasználása és az alkalmazható képjavító eljárások összefoglalása.

A shader effektek alkalmazása lehetővé teszi, hogy szebb színeket, élesebb képet, esetlegesen kissé elmosott éleket lehessen adni egy-egy képkockához. Az MPC-HC ezekkel az instrukciókkal, rövidebb-hosszabb kódsorozatokkal igyekszik mindenki igényei szerinti képminőséget nyújtani. Természetesen a kombinálásra is lehetőség van, így elég széles paletta áll a felhasználók rendelkezésére.

A shaderek használata a videólejátszáshoz (képtovábbítás) manapság tipikusan a GPGPU (General-Purpose computing on Graphics Processing Unit) műveletek közé tartozik. A denoise, deinterlacing, színkorrekció mind-mind tipikusan ilyen műveletek.

Tesztünk során több fórumozó kollégával karöltve vizsgáltuk meg, hogy hogyan is teljesítenek a tipikusan HTPC-ben felbukkanó low-end kártyák és a kicsit erősebbek. Itt ragadom meg az alkalmat, hogy köszönetet mondjak (betűrendben) band1103, CPT.Pirk, PuMbA és WonderCSabo kollégáknak a hathatós és értékes segítségért.

Shader - nagy vonalakban

Shader - nagy vonalakban

Hirdetés

A shaderek (magyarul: árnyalók) speciális számolóegységek a videokártyákon. Olyan instrukciók, amelyek a megjelenítés bizonyos effektjeit, az objektumra eső árnyékokat, vagyis a színeket számolják. Innen ered a neve is. Praktikusan a GPU megjelenítő pipeline-jának programozására használhatóak, egyedi hatásokkal bővítve működését.

Programozására a GLSL (OpenGL Shading Language), illetve a Direct3D API-ra alapozó HLSL (High Level Shading Language) használható. A GLSL első sorban a platformfüggetlenségre törekszik, a HLSL viszont a Microsoft fejlesztése és szinte együtt fejődik az nVidia Cg nyelvével.

A programozás mögött nem kell valami ördögi dologra gondolni. A HLSL egyik nagy előnye például, hogy a Microsoft a DirectX-hez hasonlóvá tette a fejlesztést, így aki ismeri a DirectX programozásra is használatos C nyelvet, ismeri a shaderek programozásának a nyelvét is (nagyjából).

A már említett GPGPU technika ötlete hívta életre a "kivülről is programozható GPU" megalkotását, illetve a programozható shaderek kidolgozását. Ma már univerzális shaderekkel találkozhatunk, vagyis unified shaderekkel, de régebben külön volt a vertex, a pixel és később a geometry shader egység és külön futószalagokat, időzítőket is használtak a gyártók. Az összevonásnak a legfőbb oka a teljesítmény jobb kihasználása volt. Az eredmény egy általános számoló egység lett, amely mindhárom műveletre kiosztható. A DirectX 10 megjelenése hozta a geometry shadereket, illetve a vele megjelenő Shader Model 4 általánosította a pixel, vertex, geometry shaderek specifikációját, így még könnyebbé vált a programozásuk.

Ahogy látható, sokkal hatékonyabb összevonni a különböző shadereket a kihasználtság szempontjából
/forrás: mips.com/

Kezdetben az ATI használta az összevont egységeket, de ők is főleg az Xbox-ban tesztelték. Az nVidia tiltakozott az egész koncepció ellen, de aztán végül ők mutatták be elsőként a G80 újdonságaként a unified shader modellt és nem sokra rá az R600-ban is megjelent az ATI részéről a PC-s vonalon.

Unified shader egységek tömörülnek össze a stream processzorokban, amelyeknek egyetlen feladata, hogy a bemenő adatfolyamon egy előre meghatározott műveletet végezzenek el, majd a kimenetre tegyék a módosított adatfolyamot - tulajdonképpen különálló ALU-k. Ezekből a shadereket 16-os blokkokba szerveződő stream processzorokból több százat is implementálnak egy-egy modern grafikus kártyára. Az egyszerű műveletek és a gyors végrehajtás, valamint a nagy számuk miatt elég jelentős számítási teljesítmény rejlik bennük, amire szükség is lehet, hiszen egy teljes képernyős kép több millió pixelt is tartalmazhat.

A kiszámolt hatásokat (effektek), mint antialiasing, HDR, multisampling végül a ROP (Raster Operations Pipeline) egységek teszik láthatóvá a puffereken keresztül, így ezek száma sem elhanyagolható.

Dióhéjban összefoglalva
/forás: Multimedia VLSI Lab/

CUDA és a shaderek

Kapcsolódik a témához, így érdemes megemlíteni, hogy az nVidia már jó ideje alkalmazza az úgynevezett CUDA (Compute Unified Device Architecture) egységeit, amely a unified shaderekre épül. Persze azért kicsit más, mint a shaderek. A shaderek alapvetően minden pixelt diszkretizálnak (raszterizálnak), vagyis minden pixel elindít egy shadert (programot). A CUDA ezzel szemben a többszálú programozáshoz nagyon hasonló elven működik. Több szálat indíthatunk és ezek a szálak több pixelt is kezelhetnek egyszerre. A shaderek viszont gyors upsampling és downsampling műveletekre is képesek, amire a CUDA nem.

Mivel külső programozási nyelvekkel (pl.: C) általános feladatokra is programozhatóak és így masszívan párhuzamosítható, többszálas műveletek számításait is ki lehet osztani ezeknek az egységeknek, amelyek messze leköröznek egy hagyományos processzort. Érdekes, hogy jelenleg a CUDA előrébb tart a fejlődésben, mint az ATI, holott először elvetették még az ötletét is a unified shadereknek, így még SDK-t is az ATI adott ki először (2006 nyarán, Stream néven), amit végül ATI Streamnek neveztek el. A CUDA népszerűsége kétségtelen, de hátránya, hogy csak nVidia kártyákon használhatóak, míg az ATI törekvése egy általános megoldás szállítása.

Shaderek és a videózás

Mivel a stream processzorok általános célokat szolgálnak, befoghatóak multimédiás célokra, akár videofolyamok dekódolásának bizonyos részfolyamataiba is. (Ezt használja ki elég jól a CUDA a DXVA API-n keresztül nem dekódolható HD filmek GPU általi dekódolásában is.) Egy-egy keret dekódolása után úgynevezett post process műveletek végezhetőek még el a képen a shaderek segítségével az eredmény javítására. Tipikusan ilyenek a szűrők alkalmazása, a képjavító eljárások, színkorrekció (színtérváltás). Ezek némelyike igencsak számításigényes feladat és a kevés shader egységet tartalmazó, alsóbb kategóriás grafikus kártyák ilyenkor rendesen meg is szenvedhetnek a műveletek elvégzésével, nem beszélve a szoftveres optimalizáltság fontosságáról. Mivel a shader utasítások nem több ezer soros programkódok, oda kell figyelni - a teljesítmény fokozása érdekében - egy hatékony kód írására.

És itt érkeztünk el a történetben az MPC-HC shader opciójához... A műveletekhez legalább egy Shader Model 2.0 verziót ismerő DirectX 9-es VGA szükséges. Ez a modell tartalmazza azokat az alapvető utasításokat, amelyeket végre tud hajtani egy-egy stream processzor.

MPC-HC és a shaderek

MPC-HC és a shaderek

Előfeltételek, követelmények:
- Egy videokártya legalább Shader Model 2-vel - a Dx9-es kártyák már ilyenek.
- DirectX 9 runtime (lehetőleg a legfrissebb).
- VMR7/9 (renderless) vagy EVR custom megjelenítő.
- 3D felületek beállítása
- az MPC-HC egy példánya, amely a 727-es build-nél frissebb (ezt nem lesz nehéz teljesíteni, mert ez már elég régi)

Az alkalmazás beállítása roppant egyszerű, gyakorlatilag egy kontext menüben elérhető funkcióról van szó. Betöltünk egy filmet, jobb kattintással előcsalogatjuk a helyi menüt és ott kiválasztjuk a Shaders (Árnyalók) menüt. Alapesetben le vannak tiltva ezek a hatások, mert bizony, mint látni fogjuk, nem minden GPU tud megbirkózni egy-egy komolyabb terhelést jelentő programocskával.

Éppen ezért érdemes monitorozni a teljesítményt és egy feladatkezelőt (task manager) is nyitva tartani arra az esetre, ha túl megterhelő lenne a művelet a GPU-nak.

Az árnyalók nagyobb része önmagáért beszél és néhány perc próbálgatással könnyen kitalálható, melyik mire való. Többségük inkább csak poén vagy látványos (mint pl. az éjjellátó funkció), azonban van néhány, amelyek alkalmasak a képminőség befolyásolására (post process), viszont cserébe megdolgoztatják a GPU-t a számításokkal. Most nem sorolnám fel mindet, hanem forduljunk is rögtön a fontosabbakhoz, amelyeknek komoly szerepük lehet a képminőségben.

A shaderek önmagukban is használhatóak, így nem is terhelik meg nagyon látványosan a GPU-t, egy-két kivételtől eltekintve, tehát azoknak, akiknek gyengébb grafikus megjelenítőjük van, érdemes egyesével próbálgatni a beállításokat.

Shaders/Screen Space Shaders

Az első, amit érdemes megfigyelni, hogy a fejlesztők szerencsére logikusan gondolkodtak, amikor a shaderek bevetéséről döntöttek. Alapesetben, ha egy filmet nézünk, ami mondjuk 1280x720 felbontású, ám azt szeretnénk például az 1680x1050 felbontású monitorunkon nézni, az történik, hogy a shaderek alkalmazásával először végrehajtódnak a shader utasítások, majd átméreteződik a kép. Ez nyilván elég sok számítást igényelő feladat.

Amennyiben azonban a Screen Space shadereket használjuk, akkor először átméretezi a képet a program és utána hajtja végre a shader utasításokat. Ez is számításigényes, de az előzőnél optimalizáltabb megoldás.

Ha tehát például az élességet befolyásoló effektet használunk, érdemesebb a Screen Space hatásokat választani.

Képélesség:

Ha rendezzük az effekteket, akkor az első csoportba az élességet befolyásoló shaderek kerülhetnek. Ezek fő feladata, hogy az elmosódott, halványabb részek is élesebbek legyenek lejátszás közben.

Ide tartozik a sharpen complex 2, sharpen complex, edge sharpen, sharpen. Erősségük ebben a sorrendben állítható sorba. Alkalmazható több is közülük, de nem ajánlott, illetve többször ugyanazt sem ajánlott betenni, mert könnyen a ló másik oldalára eshet a képminőség és egy-egy él olyan lesz, mint egy sündisznó.

Közepesen számításigényes shaderek.

Színek:

Anélkül, hogy a színterek közötti konverzióba mélyebben belemennék, nézzük meg a színterekre vonatkozó shadereket. Ezek nem terhelik meg túlságosan a GPU-t, de hatásuk látványos lehet adott esetben.

16-235-->0-255[SD][HD]
Ez a shader a színskálát terjeszti ki. Az alap probléma az RGB és a YUV közötti konverzióból, illetve annak veszteséges voltából ered. Az RGB 0-255 értékeket tárol, ezekből a konverzió során a 16-235 közötti Y marad meg. A YUV tehát nem használja a teljes 0-255 tartományt. Ennek történelmi okai vannak, de ebbe most ne menjünk bele. A lényeg, hogy ez a shader segít a színek teljes 16 milliós tartományát visszaállítani 11 millió helyett.

Érdekesség, hogy régebben erre nem volt lehetőség, ám az nVidia és az ATI is egy ideje már beépítette a grafikus kártyái driver-ébe a korrekciót. Ettől függetlenül kipróbáltam a shadert és a különbség észrevehető. Igazán látványosan lejátszás közben változik meg a kép.

BT601 —> BT709
Kicsit tovább menve a színterek világában, nézzük meg a BT601 —> BT709 shadert. A YUV és RGB közti konverzióhoz választja ki a színteret. Az ITU-R BT.601 általában az SD, míg az ITU-R BT.709 a HD tartalmakhoz tartozik. Az RGB csökkentett tartományát befolyásolhatja a helyes használat.

Denoise

A denoise nevéből eredően a zajszűrésre koncentrál. Minden shader közül ez a legerőforrásigényesebb és ahogyan a tesztünkből látni fogjuk, nem alaptalan ez a kijelentés. Hátulütője, hogy indokolatlan használata elmosottá, homályossá teszi a képet, ahelyett, hogy javítaná a minőségét. Éppen ezért érdemes mindig kipróbálni, hogy az adott filmnél javít-e vagy ront. Használatát érdemes kombinálni az élességért felelős shaderekkel, így egymás hatását enyhíthetik, ha valamelyik túl sok lenne.

Ma már a VGA driver-ben is van denoise, azt is megéri kipróbálni, mert valamivel okosabbra vannak megírva, mint ez a shader, amely minden keretre külön alkalmazza a zajszűrést.

Deinterlace

A deinterlace használata nem szükséges az esetek túlnyomó többségében, de tévéből felvett adásoknál hasznos lehet, ha interlaced maradt a folyam (pl.: 1080i).

Shaderek kombinálása

A legelterjedtebb a shaderek kombinálása a legjobb képminőség elérése érdekében. Ezek közül is az egyik legnépszerűbb kombináció a következő hármas a felhasználók körében:
- sharpen copmplex 2
- denoise
- 16-235-->0-255

A különbség látványos a shadereket engedélyezése és tiltása között:

Kiemelhető még az is, hogy a shaderek szabadon szerkeszthetőek a beépített editorral. Szerencsére úgy oldották meg a készítők a szerkesztést, hogy a programok átírásának hatása azonnal meg is jelenik a képernyőn. (Sajnos a denoise-t nem sikerül sem okosabbra, sem kevésbé erőforrásigényesre átírnom).

Teszt

Teszt

Tesztünk célja az volt, hogy az erőforrásra érzékenyebb shaderek használatának hatásait megnézzük különböző grafikus kártyákkal. HTPC-be általában egy alsó kategóriás VGA-t választanak az emberek, de vajon ezek elegendőek a képjavító eljárások mindegyikéhez?

A teszt résztvevőit és azok főbb paramétereit a következő táblázat foglalja össze:

Látható, hogy vannak több száz shader processzort tartalmazó versenyző is, míg vannak, amelyeknek nem jutott túl sok ezekből. Legnagyobb mértékben ezeknek az egységeknek és ehhez kapcsolódóan a ROP-oknak a száma határozza meg, hogy például egy denoise shader mennyire hat ki a lejátszás folyamatosságára.

A VGA-n kívül a többi hardver jelen esetben lényegtelen.

A tesztet az említett hármas kombinációval végeztük el:
- sharpen copmplex 2
- denoise
- 16-235-->0-255

A tesztelésre kiválasztott videó ezen az oldalon érhető el a ">> Download <<"-ra kattintva.

Nos, lássuk tehát az eredményeket és vonjuk le a következtetéseket.

A csillaggal jelölteknél a 0-s érték természetesen mérési hiba, illetve az X4500 sem volt hajlandó túl sokat elárulni magáról.

Talán szemléletesebb ez az ábra, mint a táblázat. Természetesen a 100% körüli terhelés élvezhetetlen lejátszást is eredményezett, így ezeknél az említett kombináció nem jó ötlet.

Bebizonyosodott tehát, hogy a GPU-t igencsak meg lehet dolgoztatni a shaderek alkalmazásával, kombinálásukkal. Sajnos az is látható, hogy az alsó kategória belépő kártyái nem igazán alkalmasak az árnyalók használatára (legalábbis nem érdemes a legdurvábbakat bevetni). Megéri kipróbálni a VGA driver-ben rejlő lehetőségeket annak, aki még nem tette, hogy azzal is csökkentse a GPU kihasználtságát.

A 8800GT viszonylag magas, 1500 MHz-es shader sebessége sokat segíthetett a lejátszásnál, így kompenzálva a shader egységek számát.

Érdemes a Screen Space árnyalókat használni, mert a fent említett hármas kombinációt használva a GPU terhelése kevesebb lehet. (A 100%-os terhelésen sajnos nem sokat segít ez sem.)

Ha a denoise-t, mint terhelésre éhes hatást kivesszük a sorból, akkor már elfogadható és használható terhelés mellett élvezhető a többi shader hatása.

Érdekes eredmény még, hogy amikor kombinált shaderekkel a HD 5670 60% kihasználtságot produkált és kivettem a denoise-t, csupán az eredeti felére esett vissza a terhelés (30% körül), míg amikor egyedül a denoise volt aktív, akkor kiterhelte egymaga 46%-ra a GPU-t. Mivel nem csak ezzel a shaderrel fordult elő a jelenség, szoftveres gondra gyanakszom (vagy driver vagy az MPC-HC).

Érdekes lett volna még kipróbálni egy ION-os rendszert, illetve egy GMA HD-set, de gyanítom, hogy az ION 16 SP-je és a GMA HD 12 egysége nem villantana nagyot a denoise-t engedélyezve.

További eredmények más videókkal, régebbről:

Itt jegyzem meg iMaverick kolléga tesztjét is, akinek a HD 5770 DXVA nélküli lejátszással (egy másik videónál) 88% körüli terhelést produkált (nem Screen Space shaderekkel) - esetleg kipróbálhatod ez utóbbi módszerrel is, ha minden igaz, látványosan csökkenni fog a kihasználtság.

FF23 barátunk is tesztelt egy picit az nVidia 210 kártyáját megdolgoztatva. Nála órajel emeléssel is élvezhetetlen volt a lejátszás és érdekesség, hogy a shaderek engedélyezése a Video Engine terhelését csökkentette, míg tiltásukkal az egység visszavette az irányítást. A shaderekkel terhelt lejátszás nagyjából 14W plusz terhelést is jelentett az összes fogyasztásban.

Végszó

Végszó

Mit is lehetne írni végszó gyanánt? Általánosságban elmondható a látottak alapján, hogy a shaderek használata adott esetben jótékony hatással lehet a képminőségre, de vannak olyanok, amelyek használata driver-ből kiváltható (denoise) és akkor kevesebb erőforrást igényel. Érdemes filmnézés előtt kipróbálni, hogy a kedvenc shadereink vajon feleslegesen emésztik-e fel a GPU terheltségét vagy valóban látható hatásuk van.

Az árnyoldalakat vizsgálva általános érvényű az a kijelentés, hogy minél több shader egység (és ROP) dolgozik a VGA oldalán, annál hatékonyabban használhatóak a shaderek. A legjobban terhelőket nagyjából 100 SP alatt nem is nagyn érdemes próbálgatni, mert élvezhetetlen lesz a lejátszás.

A shaderek programozására is lehetőséget nyújt az MPC-HC, így szabad kezet kap a felhasználó abban, hogy tesztre tudja szabni ezeket a kis programokat. Sajnos a shaderek programozása nem nagyon hasonlít a magas szintű nyelvekhez, de azért lehet velük alap szinten boldogulni.

A felhasználó szemszögéből nézve a legjobb az lenne, ha a CUDA párhuzamosíthatóságát és viszonylag könnyű programozhatóságát a shaderek hatékonyságával és a CUDA korlátait átlépő tudásával (mipmapping, upsampling, downsampling) ötvöznénk - persze ez kicsit utópisztikus.

Végül mindenkinek csak azt tudom javasolni, hogy próbálgassa a lehetőségeket és keresse meg a neki optimális beállítást, kombinációt.

Előzmények