Jaka jest zaleta mechanizmu bezpośredniego dostępu do stanu OpenGL?

11

Czytałem o OpenGL 4.5 Direct State Access (DSA) na opengl.org i nie jestem pewien, czy mam rację.

Wydaje się sugerować, że stary sposób jest mniej wydajny:

glBind(something)
glSetA(..)
glSetB(..)
glSetC(..)

niż nowy sposób:

glSetA(something, ..)
glSetB(something, ..)
glSetC(something, ..)

Wygląda na to, że teraz każdy glSetmusi się w nim zawierać glBind(something), a jeśli OpenGL nadal jest maszyną stanu, nie może skorzystać ze strumieniowych zmian zastosowanych do jednego something.

Proszę wyjaśnić uzasadnienie i zalety nowego DSA.

Kromster
źródło

Odpowiedzi:

21

Z wyglądu teraz każdy glSet musi zawierać w sobie glBind (coś)

Nie dokładnie. Odwrotnie, jak opisano w kilku akapitach poniżej.

Nawet jeśli to prawda, pamiętaj, że polecenia GL z aplikacji klienckiej do serwera GL (zwanego również sterownikiem) mają dużo narzutu wysyłki w porównaniu do zwykłego wywołania funkcji. Nawet jeśli założymy, że funkcje DSA są tylko opakowaniami wokół istniejących funkcji, są to opakowania, które znajdują się wewnątrz serwera GL, a zatem mogą mieć (trochę) mniejszy narzut.

jeśli OpenGL nadal jest maszyną stanu, nie może skorzystać ze strumieniowych zmian zastosowanych do pojedynczego elementu.

Procesory graficzne nie są maszynami stanu. Interfejs maszyny stanów GL jest emulacją, która otacza wewnętrzne sterowniki podobne do DSA, a nie na odwrót.

Usunięcie jednej warstwy opakowania - warstwy wymagającej nadmiernej liczby wywołań do serwera GL - jest wyraźnie wygrane, nawet jeśli jest małe.

Podejście oparte na maszynie stanów również nie ma sensu w przypadku wielu wątków; GL jest nadal okropny w tym przypadku użycia, ale sterowniki często używają wątków za kulisami, a maszyna stanów wymaga dużo synchronizacji wątków lub naprawdę wymyślnych algorytmów / konstrukcji równoległych, aby działać niezawodnie.

Rozszerzenie DSA nadal określa swoje działanie w kategoriach zmian stanu, ponieważ jest to w końcu rozszerzenie istniejącego dokumentu opartego na stanie, a nie całkiem nowy interfejs API, więc musiał być gotowy do podłączenia do istniejącej specyfikacji GL język dokumentu i terminologia. Nawet jeśli ten istniejący język bardzo dobrze nadaje się do pracy jako nowoczesny sprzętowy interfejs API grafiki.

Proszę wyjaśnić uzasadnienie i zalety nowego DSA.

Największym powodem jest to, że stary sposób był bólem. Bardzo utrudniało to tworzenie bibliotek, które mogłyby modyfikować lub polegać na stanie GL. Utrudniało to wydajne pakowanie interfejsu API GL w obiektowy lub funkcjonalny styl ze względu na głębokie korzenie zarządzania stanem proceduralnym, co utrudniało pakowanie interfejsu API w różnych językach innych niż C, a także utrudniało zapewnienie wydajnych opakowań urządzeń graficznych ten abstrakcyjny OpenGL z Direct3D.

Drugi to narzut proceduralny interfejsu API maszyny stanów, jak opisano wcześniej.

Po trzecie, funkcje DSA w stosownych przypadkach zmieniły semantykę ze starych interfejsów API, które umożliwiały lepszą wydajność. Rzeczy, które wcześniej podlegały mutacjom, stały się na przykład niezmienne, co usuwa wiele kodów księgowych z serwera GL. Wywołania aplikacji mogą być wysyłane do sprzętu lub sprawdzane wcześniej (lub w bardziej równoległych modach), gdy serwer GL nie musi zajmować się obiektami zmiennymi.

-

Dodatkowe uzasadnienie i wyjaśnienie podano w specyfikacji rozszerzenia EXT_direct_state_access .

-

Zmiany sprzętowe istotne dla projektu interfejsu API są dość liczne.

Pamiętaj, że OpenGL pochodzi z 1991 roku. Docelowym sprzętem nie były karty graficzne klasy konsumenckiej (te nie istniały), ale duże stacje robocze CAD i tym podobne. Sprzęt tej epoki miał bardzo różne koperty wydajności niż dzisiaj; wielowątkowość była rzadsza, szyny pamięci i procesory miały mniejszą lukę prędkości, a GPU niewiele więcej niż renderowanie trójkątów o stałej funkcji.

Dodano coraz więcej funkcji o stałej funkcji. Dodano różne modele oświetlenia, tryby tekstur itp., Każdy z nich wymagał własnego stanu. Proste podejście oparte na stanach zadziałało, gdy masz garść stanów. W miarę dodawania coraz większej liczby stanów interfejs API zaczął pękać w szwach. Interfejs API stał się bardziej niezręczny, ale nie odbiegał zbytnio od trybów sprzętowych, ponieważ faktycznie były oparte na wielu przełącznikach stanu.

Potem pojawił się programowalny sprzęt. Sprzęt stał się coraz bardziej programowalny, do tego stopnia, że ​​teraz obsługuje mały stan, niektóre programy dostarczone przez użytkownika i wiele buforów. Cały ten stan z poprzedniej epoki musiał zostać naśladowany, podobnie jak wszystkie funkcje o ustalonej funkcji z tej epoki były emulowane przez sterowniki.

Zmieniono także sprzęt, aby był coraz bardziej równoległy. Wymagało to innych przeprojektowań sprzętu, które spowodowały, że zmiany stanu grafiki były bardzo kosztowne. Sprzęt działa w dużych blokach niezmiennego stanu. Z powodu tych zmian sterownik nie mógł po prostu zastosować każdego fragmentu stanu, który użytkownik ustawił natychmiast, ale musiał wsadowo wprowadzić zmiany automatycznie i zastosować je w razie potrzeby niejawnie.

Nowoczesny sprzęt działa jeszcze dalej niż klasyczny model OpenGL. DSA to jedna mała zmiana, która była potrzebna około 10 lat temu (pierwotnie była obiecana jako część OpenGL 3.0), podobnie jak to zrobiła D3D10. Wiele powyższych zmian sprzętowych wymaga znacznie więcej niż tylko DSA, aby zachować odpowiedni OpenGL, dlatego dostępnych jest jeszcze więcej dużych rozszerzeń, które drastycznie zmieniają model OpenGL . Jest też zupełnie nowy interfejs GLnext API plus D3D12, płaszcz, metal itp., Z których żaden nie utrzymuje przestarzałej abstrakcji maszyny stanu.

Sean Middleditch
źródło
Dziękuję za odpowiedź. Wydaje się więc, że wcześniej maszyna stanu (nie DSA) była wygrana, ale w pewnym momencie coś się zmieniło i teraz DSA jest korzystne. Czy możesz rzucić nieco światła na to, co się zmieniło?
Kromster
@KromStern: dałem z siebie wszystko. Jeśli potrzebujesz więcej szczegółów, ktoś bardziej kompetentny niż ja będzie musiał je dostarczyć.
Sean Middleditch,
@KromStern Widziałem (z moich ograniczonych badań nad historią), jak OpenGL przechodzi do coraz mniej wywołań po stronie procesora na ramkę; wyświetl listy (za ile były warte), glDrawArrays (rysuj w jednym wywołaniu), VBO (przesyłaj do GPU raz), VAO (wiąż bufory z atrybutami raz), jednolity obiekt buforowy (ustaw mundury za jednym razem). Jestem pewien, że brakuje mi czegoś więcej.
maniak zapadkowy
@ratchetfreak: co zabawne, idziemy teraz w drugą stronę. Nowoczesne interfejsy API / rozszerzenia koncentrują się na zwiększeniu liczby wywołań rysujących na ramkę, głównie poprzez usunięcie całego stanu, który musi zostać ustawiony / wysłany na wywołanie losowe i wykonywanie wywołań niewiele więcej niż „wstawienie polecenia rysowania do kolejki poleceń” przeciwko dużej zestaw stanu statycznego i niewiążących zasobów. Oooh, niewiążący, zapomniałem nawet wspomnieć o tej części mojej odpowiedzi.
Sean Middleditch,
@SeanMiddleditch Powinienem ustawić wywołania na ramkę.
maniak zapadkowy
1

Przegląd uzasadnia to:

Celem tego rozszerzenia jest zwiększenie wydajności bibliotek w celu uniknięcia zakłócania selektora i stanu zatrzaśnięcia. Rozszerzenie pozwala również na bardziej wydajne korzystanie z poleceń, eliminując potrzebę używania poleceń aktualizacji selektora.

Myślę, że „bardziej wydajny” odnosi się tutaj zarówno do mniejszego obciążenia księgowego autorów bibliotek, jak i do wyższej wydajności. Przy obecnym interfejsie API, aby być „dobrze zachowanym”, należy zapytać o stan, ukryć go, zmienić stan, aby zrobić to, czego potrzebujesz, a następnie przywrócić pierwotny stan.

Lubić

oldState = glGet()
glBind()
glDoThings...
glSet(oldState)  // restore, in case anyone needs it just as they left it

Można przypuszczać, że starszy sprzęt mógłby być bardziej wydajny dzięki jawnemu API zmieniającemu stan; w przeciwnym razie to dość dziwny rytuał. To rozszerzenie sugeruje (i spójrz tylko na listę autorów!), Że unikanie pobierania, ustawiania i przywracania tańca jest teraz bardziej wygraną wydajności na obecnym sprzęcie, nawet z dodatkowym parametrem dla każdego połączenia.

David Van Brink
źródło
„trzeba wysłać zapytanie / ukryć / zmienić / przywrócić” - jak to jest lepiej w DSA?
Kromster
..Dodano pseudo kod do wyświetlenia. W przypadku DSA nic z tego nie jest konieczne. Prawdopodobnie obecny sprzęt tak naprawdę nie potrzebuje stanu „wiązania”, może po prostu uzyskać dostęp do wszystkich w razie potrzeby.
David Van Brink
Łańcuch get/bind/do/setjest rzadko używany, ponieważ „Get” jest bardzo wolny. Zazwyczaj aplikacje i tak muszą utrzymywać replikę zmiennych, więc ogranicza się do tylko bind/do. Widzę jednak sens.
Kromster
2
@krom get ze stanu sterownika może być szybki, niektóre ze stanu gettable nie mają żadnego interesu na GPU, więc można je po prostu pobrać z szybkiej pamięci RAM.
maniak zapadkowy