Autor Wątek: [Android] Shadery, osobne wątki, gdzie i jak tworzyć i zwalniać zasoby?  (Przeczytany 3488 razy)

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Październik 22, 2012, 10:15:52
Witam,
Od jakichś kilku miesięcy portuję xenona na androida i jak dotąd szło dobrz, prawie każdy problem większy znajdował odpowiedź na stackoverflow, aż do teraz. Mianowicie:
Mam ja sobie osobne wątki logiki i renderingu i próbuję stworzyć zasób shadera. Najpierw próbowałem go stworzyć w wątku logiki, ale jak wiadomo, można je tworzyć tylko w wątku renderingu, tak więc też zrobiłem, lecz funkcje tworzące shader nadal zwracają 0 (czyli błąd). Gdzie i jak tworze te shadery:
mam ja sobie system maszyny stanów w wątku logiki, w onEnter() wrzucanego na stos stanu wywołuję coś w stylu:
renderView.queueEvent(new Runnable(){public void run()
{
int id = GLES20.glCreateShader();
// inne akcje i sprawdzanie debugowe czy wartość jest poprawna
}});
wszędzie gdzie widziałęm kod, zasoby były tworzone w onSurfaceCreate() render view, a więc czy jest to koniecznością, aby tylko i wyłącznie w tej metodzie tworzyć zasoby? martwi mnie to, bo to rujnuje system maszyny stanów, który w tym przypadku jest bezużyteczny oraz nie będę mógł w takim przypadku dynamicznie tworzyć i zwalniać zasobów.
Bardzo proszę o podpowiedź, co mogę zrobić, aby poprawnie utworzyć zasoby?
Z góry dziękuję!

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

  • +1
# Październik 22, 2012, 10:36:44
Cytuj
lecz funkcje tworzące shader nadal zwracają 0 (czyli błąd)
A błędy z kompilacji sprawdzałeś? Bo jak kompilacja shadera zwraca błąd, to driver powinien się jakoś przed tobą z tego wytłumaczyć.

No i pamiętaj, że na fizycznym urządzeniu nie wiesz jaki driver dostaniesz, więc spodziewaj się wszelkiego rodzaju faili kompilacji. Nawet tam, gdzie shader jest całkowicie poprawny driver może się wysypać. Przykładowo na Samsungu Galaxy S nie polecam w ogóle używać makr ani niczego co zaczyna się od #. Mi w najlepszym przypadku zwracało errory z głupotami, a w najgorszym crashowało aplikację* ze stack tracem pokazującym gdzieś w kod drivera.

*) Efekt taki da się osiągnąć linijką "#define float2 vec2". Nie mam pojęcia jak oni pisali ten kompilator, ale słowo "float" w nazwie makra powoduje crash. Ale nie jest to w praktyce problemem, bo na tym Samsungu makra same z siebie i tak są nie do użytku. Jeżeli potrzebujesz to polecam postawić własny makroprocesor.

EDIT: I żeby nie było: crashujący shader był 100% poprawny - przechodził walidację przez malisc i działał poprawnie na ARMowym emulatorze OpenGL ES 2.0.


I tak - spodziewaj się więcej faili tego rodzaju, zależnych od konkretnego modelu sprzętu i drivera. All the joy of GLSL. :)


Cytuj
wszędzie gdzie widziałęm kod, zasoby były tworzone w onSurfaceCreate() render view, a więc czy jest to koniecznością, aby tylko i wyłącznie w tej metodzie tworzyć zasoby?
Nie. Zasoby możesz tworzyć w dowolnym momencie, byle w wątku renderującym. Ja załatwiłem to u siebie tak, że wątek UI kolejkuje zdarzenia, które są przetwarzane w momencie callbacka do renderingu z SurfaceView, więc nie muszę się martwić bo mam wszystko w efekcie jednowątkowo. :)

Offline .:NOXY:.

  • Użytkownik
    • Profil

# Październik 22, 2012, 11:13:39
Krzychu dobrze mowi zerknij na logi nie masz pojecia jak na Mobilnych shadery szaleja :) 90% przypadkow z podowu precision jest bo sie typy nie podobaja i ogolnie ogromnego okrojenia sie spodziewaj.

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

  • +1
# Październik 22, 2012, 11:21:05
Panowie, jaki log z kompilacji, skoro na glCreateShader() zwraca 0, a nie można kompilować nieistniejącego shadera ;)

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Październik 22, 2012, 11:54:02
No nie powiedziałeś które funkcje zwracają zero, to założyłem że te od kompilacji. :)

W takim razie sprawdź, czy w onSurfaceCreated Ci to zadziała. Jeżeli nie, to najwyraźniej problem jest z kontekstem (np. wybrał się ES 1.1), albo w ogóle go nie ma. Jeżeli zadziała, to upewnij się, że tworzysz zasoby po tym, jak już masz kontekst (a nie np. w wątku renderującym ale przed utworzeniem kontekstu). No i generalnie debug log Twoim przyjacielem jest. Jak nie wiesz co się dzieje, to printuj gdzie jesteś i co robisz. A na start chociaż komunikaty o tworzeniu shadera i inicjalizacji kontekstu, żeby mieć pewność że chociaż to jest we właściwej kolejności.

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Październik 22, 2012, 12:16:32
hmm, kontekst na bank tworzy się gles 2.0 i na bank przed odpaleniem maszyny stanów - wymuszona kolejność taka przez silnik, a gdyby nei utworzył się kontekst 2.0 to by wyłączyło apke w ramach zabezpiecznia. Spróbuje jeszcze pobrać tekst z glGetError po glCreateShader - może jakoś pomoże. Aha, całość koduje jak i testuje na urządzeniu (Galaxy Pocket), więc tut też nie mam problemu z różnicami emulator<->device.
Wieczorem dam znać co dały Wasze rady :)

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Październik 22, 2012, 21:42:24
cholera, faktycznie zle blokowalem watek logiki poki rendering nie bedzie gotow :0
zastanawia mnie tylko, ze logi kompilacji wygladaja na jakby uciete:
shadery: "compile"
program: "missing main function of shade"
wtf? :D
czy glGetShaderInfoLog() zwraca stringa  kodowaniu innym niz utf-8? oraz z racji, ze debugowo sprawdzam tresc wczytanego shadera  jest on dobry, to czy musze przekoowac tresc z utf-8 na jakies inne kodowanie dla glSetShaderSource()?
« Ostatnia zmiana: Październik 22, 2012, 21:51:29 wysłana przez ΨΧΞ »

Offline FoToN

  • Użytkownik

# Październik 22, 2012, 23:02:14
Ja miałem u siebie przypadek, że pobrana długość logu nie była zgodna z rzeczywistą. Tzn. jak dałem potem char buffer[512], lub jakiś inny większy kawałek pamięci to dostałem cały log ;)

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Październik 22, 2012, 23:34:23
Cytuj
zastanawia mnie tylko, ze logi kompilacji wygladaja na jakby uciete:
shadery: "compile"
program: "missing main function of shade"
Brak fflush(my_file) czy coś w tym stylu? ;)

Cytuj
czy glGetShaderInfoLog() zwraca stringa  kodowaniu innym niz utf-8?
Pewnie zwraca w zwykłym ASCII.

Cytuj
oraz z racji, ze debugowo sprawdzam tresc wczytanego shadera  jest on dobry, to czy musze przekoowac tresc z utf-8 na jakies inne kodowanie dla glSetShaderSource()?
Nie sądzę, żeby zrozumiał UTF-8. Zwłaszcza że żaden ze znaków spoza ASCII nie jest chyba dozwolony w GLSL.

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Październik 24, 2012, 09:39:30
hmm, zastosowałem rady Krzyśka i podziałało wszytko, shadery się ładnei kompilują - dziękuję :)
no to zostało teraz zrobić vbo i tekstury i można tworzyć pierwsze demo gry! :D

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Październik 24, 2012, 09:50:18
hmm, zastosowałem rady Krzyśka i podziałało wszytko, shadery się ładnei kompilują - dziękuję :)
no to zostało teraz zrobić vbo i tekstury i można tworzyć pierwsze demo gry! :D
Do czego Ci VBO w silniku 2D?

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Październik 24, 2012, 10:35:15
do spritebatcha - duuuużo sprajtów będzie i chciałem to zoptymalizować

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Październik 24, 2012, 10:40:48
do spritebatcha - duuuużo sprajtów będzie i chciałem to zoptymalizować
VBO głównie nadaje się do statycznej geometrii. Do geometrii dynamicznej nie będzie to wiele szybsze od Vertex Array, jeżeli w ogóle. Do tego biorąc pod uwagę fakt, że robiąc dynamiczne VBO można coś bardzo łatwo skopać, w takim przypadku osobiście zawsze wybieram VA, które nad dynamicznym VBO może mieć narzut dodatkowego kopiowania (jeżeli robisz Map/Unmap - przy Buffer(Sub)Data VA będzie zawsze niegorsze), ale za to masz pewność, że team od drivera zrobił to w sensowny sposób dla danej architektury i GPU.

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Październik 24, 2012, 11:00:37
mówisz? hmm, w takim razie zostawię wersję z VA, dziękuję za radę!
przy okazji chciałbym spytać, czy używanie shaderów do postprocessingu (z użyciem FBO) na androidowych telefonach jest czymś normalnym i nie powoduje drastycznego spadku wydajności, czy jednak nie zaleca się tego używać póki co?
« Ostatnia zmiana: Październik 24, 2012, 11:02:10 wysłana przez ΨΧΞ »

Offline Kos

  • Użytkownik
    • kos.gd

# Październik 24, 2012, 11:03:24
Jeśli spritebatch, to dlaczego nie instancing?