.[ ČeskéHry.cz ].
Více OpenGL rendering kontextů

 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> 3D API / 3D Enginy
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
pcim



Založen: 28. 12. 2007
Příspěvky: 3

PříspěvekZaslal: 28. prosinec 2007, 10:58:55    Předmět: Více OpenGL rendering kontextů Odpovědět s citátem

Můžete mi prosím někdo objasnit následujcící ? :

Pokud mám v OpenGL více než jeden rendering kontext, a tyto kontexty mezi sebou sdílí objekty (WGL_share_lists), nese to s sebou nějakou zvýšenou režii při volání OpenGL funkcí ? Říkám si, že pokud dva thready přes dva kontexty nějak manipulují s jedním a tím samým sdíleným OpenGL objektem (např. texturou), tak přístup k objektu jako takovému musí být obalen nějakou kritickou sekcí, mutexem apod., který by v tam v případě jednoho kontextu být nemusel.

Jde mi například i situaci, kdy jeden thread čistě jen renderuje a v druhém se plní VBOs, textury apod. Samozřejmě to asi jde udělat i bez použití druhého kontextu např. pomoci glMapBuffer(), ale to už je jiná otázka.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 29. prosinec 2007, 00:13:47    Předmět: Odpovědět s citátem

Řežie tam rozhodně je a podle mě je zbytečné mít 2 kontexty, protože grafická karta dokáže v jednu chvíli obsloužit jen jeden. Když už chceš něco uploadovat za běhu, používej třeba glBufferData nebo glMapBuffer s parametrem GL_WRITE_ONLY. Ve chvíli uploadování může být aktuální buffer používán grafickou kartou a inteligentní driver zpravidla vytvoří druhý, kde uloží ty data a po dokončení práce grafické karty ho aktivuje a ten starý uvolní. To je asi nejvhodnější způsob, protože se nic nemusí zamykat a karta nemusí přerušovat svoji činnost. Nutno podotknout, že když použiješ glBufferSubData nebo glMapBuffer s jinými parametry, tohle nastat nemůže, protože si tím vynutíš editaci toho stávajícího bufferu a tam už driver musí zamykat. Zajímavá myšlenka co? - mít na kartě 2 buffery a mezi nima přepínat - zatímco se jeden plní, druhý se používá. U VBO to inteligentní drivery dělají automaticky. Jak je to u textur si nejsem jistej, ale není problém stejnou fintu naprogramovat pomocí dvou textur, že.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
pcim



Založen: 28. 12. 2007
Příspěvky: 3

PříspěvekZaslal: 29. prosinec 2007, 18:01:06    Předmět: Odpovědět s citátem

Myslel jsem si, že ty dva kontexty asi nebude to nejlepší řešení, ale zdálo se mi takhle to načítání na pozadí implementačně trochu jednoduší. Pokud bude všechen GL kód jen v renderovacím threadu, bude se zde muset např. zavolat glMapBuffer, pak nějak sdělit načítacím threadu,, že ho může naplnit a až ten to udělá tak zase sdělí rwenderovacímu threadu, že je hotov a ten pak provede glUnmapBuffer. Trochu složitější, ale nějak by se to asi udělat dalo.

To co jsi psal o přeínání více bufferů mě ale přivádí na otázku jak vlastně spravovat buffery, např. VBO. Četl jsem na to různé názory, ale stále vlastně nevím jak to správně řešit. Jsou třeba tyto dvě možnosti :

1. Každý objekt, nebo prostě něco co se rederuje v jednom render callu má svůj VBO :

Výhody :
- Implementačně jednoduché
- Alikace ani driver asi nemají problém s nějakou fragmentací bufferů
- Buffer se dá snadno a rychle naplnit a nebrzdí se tím rendering z jiných bufferů,
navíc jak píše Eosie by se driver měl postarat o vytvoření nového bufferu v případě, že by se plněný buffer právě používal pro rendering.
Nevýhody:
- Pokud se objekty načítají nabo donačítávají na pozadí až za běhu, budou se buffery vytvářet a rušit až v hlavní renderovací smyčce, což asi může brzdit.
- Častý glBindBuffer, pro každý render call se mapuje buffer(y) znovu.

2. Při startu engine se zaalokuje určitý počet poměrně velkých bufferů (např. 10 bufferů po 2MB) a ty se potom používají pro rendering všech objektů. V hlavní smyčce se žádné nové buffery nevytvářejí pouze se plní tyto existující.

Výhody :
- Žádné alokace bufferů v hlavní smyčce
- Méně časté přepínání bufferů, glBindBUffer.
Nevýhody :
- Složitější implementace, nutno vyřešit přidělování prostoru v bufferech objektům
- Při plnění dat objektu do jednoho bufferu pomocí glBufferSubData nebo glMapBuffer je třeba mít zajištěno, že z tohoto bufferu neprobíhá rendering ani žádných jiných objektů. Takže by bylo nutné vzájemně sladit pořadí renderování objektů s plněním bufferů tak, aby pokud možno nedocházelo ke kolizím.
- Problémy s framentací těchto velkých VBO

Jak to řešíte Vy ?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
tempicek



Založen: 04. 12. 2007
Příspěvky: 62

PříspěvekZaslal: 29. prosinec 2007, 18:24:26    Předmět: Odpovědět s citátem

pcim napsal:
Jak to řešíte Vy ?


Dle potreby a casu. Zalezi na projektu. Pokud to ma za neco stat, tak je treba udelat kombinaci obou pristupu, resp. pro kazdy typ dat/assetu zvolit nejlepsi pristup a naimplementovat ho (teren, velke objekty, vegetace, "odpad" ... vsechno si zada svoje).

Volani funkci grafickeho API z vice threadu je dobre se vyhnout, kdyz to trochu jde (ne za kazdou cenu). Pouziti double/tripple-bufferingu je vhodne kdekoli je s tim bufferem vice prace, zvlaste, pokud se pripravuje nekolik snimku. Idealni je to, kdyz se muzes spolehnout na driver a nechat update na nem, jak zminil Eosie.

Pro ten "drobny odpad" (projektily a jine objekty vznikajici ve vetsim mnozstvi za behu) je dobre udelat si buffery "per object type" nebo "per material", tzn. seskupovat je nejakym pravidlem k sobe tak, aby se co nejvice snizil pocet nutnych volani API (zmeny materialu a draw calls). Opet hodne zalezi na konkretni situaci kolik takovych typu je, jak jsou velke, zda neni mozne vyhradit kazdemu objektu stejny prostor atd.

Kazdopade alokovani bufferu za behu (ve vetsim mnozstvi) neni vubec dobry napad, takze tomu je rozhodne dobre se vyhnout. Kdyz ne jinak, tak alespon buffer poolem, ve kterem se vali nepouzivane (na pocatku alokovane) buffery. Tech moznosti je hodne, jako obvykle YMMV.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 30. prosinec 2007, 02:05:49    Předmět: Odpovědět s citátem

pcim> Pokud chceš méně bufferů, můžeš ho udělat interleaved - prokládaný, tzn. uložíš za sebe pozici, normálu, koordináty, pozici, normálu... atd. Pak použiješ v gl*Pointer parametr stride, kde dáš velikost celého vertexu (sizeof(pozice a normála a koordináty)), a do pointer dáš akorát offset na konkretní atribut (pro pozici 0, pro normálu ((char*)0)+sizeof(pozice), pro koordináty ((char*)0)+sizeof(pozice a normála)).
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> 3D API / 3D Enginy Časy uváděny v GMT + 1 hodina
Strana 1 z 1

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna