Różnica między „buforem” a „tablicą” w OpenGL?

12

Kiedy czytam doc na webGL lub OpenGL, można zobaczyć pewne wzorce w sposobie używania nazw funkcji i obiektów. Ale nie rozumiem różnicy między obiektem buforowym a tablicą.

Istnieją „obiekty buforów wierzchołków”, „obiekty tablic wierzchołków”, a nawet pewnego rodzaju „bufory tablic” lub „bufory tablic”.

W kontekście OpenGL, kiedy coś jest „tablicą” i kiedy zamiast tego powinno być nazywane „buforem”?

coobit
źródło
Trochę perspektywy, pomyśl o pobieraniu danych przez sieć i przechowywaniu dziennika wszystkich otrzymanych danych. Musisz odczytać gniazdo i umieścić gdzieś otrzymane dane, abyś mógł je przekazywać, to bufor. Często może to być lokalny, dynamicznie przydzielany prosty typ listy. Czasami jest to tak proste jak char* buffer = socketRead();(pseudokod). Z drugiej strony dziennik przechodzi przez cały cykl życia aplikacji. Więc gdzieś tworzysz tablicę i zaczynasz odczytywać gniazdo, za każdym razem, gdy dostajesz dane, które zapisujesz do tej porcji, dając ci uporządkowaną listę wszystkich otrzymanych danych.
Kevin

Odpowiedzi:

5

Nazywanie obiektu tablicy wierzchołków jest nieco niefortunne. Istnieją trzy różne rzeczy, które pojawiają się (lub pojawiały) w / z / wokół twojej aplikacji, i które (historycznie) zostały nazwane inaczej, z „tablicą” lub „buforem” w nazwie (no cóż, są też obiekty bufora ramki, ale zignoruję to).

  1. Dane, które znajdują się w Twojej aplikacji, formalnie i faktycznie, ale które są pobierane przez OpenGL za jednym razem (w przeciwieństwie do wierzchołka po wierzchołku). Dawno, dawno temu, nazwałbyś to tablicą wierzchołków .
    Chodziło o to, aby dostęp był bardziej efektywny, ponieważ OpenGL może po prostu skopiować całość za jednym zamachem w ściśle określonym czasie, gdy obiecałeś, że dane są spójne, i przesłać ją przez AGP lub cokolwiek w jednym bloku. To już nie istnieje.
  2. Dane ukryte i dostępne za pomocą uchwytu, który można „powiązać”, tj. Uaktywnić. Dane mogą faktycznie znajdować się w pamięci głównej lub na karcie graficznej lub zostać przeniesione do regionu, który można odwzorować na PCIe, cokolwiek, ale niezależnie od tego, czy formalnie nie jesteś właścicielem (nawet jeśli fizycznie jest w pamięci RAM i jeśli dane pochodzą z Twojej aplikacji ) - chyba że aktualnie „zmapowałeś” go za pomocą odpowiedniego interfejsu API, zwracając wskaźnik do zapisu (a czasem do odczytu). Masz również ograniczoną zdolność kontrolowania tego, co dzieje się z danymi (możesz podać kilka wskazówek, ale to w zasadzie wszystko).
    OpenGL może przenosić te dane mniej lub bardziej swobodnie, a ty zawsze możesz / możesz kopiować do / z bufora za pośrednictwem odpowiedniego interfejsu API lub uzyskiwać dostęp do danych podczas mapowania. To właśnie nazywasz obiektem buforowym ( obiekt bufora wierzchołków, jeśli zawiera wierzchołki, ale tak naprawdę nie musi, może to być również dane obrazu lub mundury, tylko wierzchołki były obsługiwane raz na raz).
    Ma to na celu zagwarantowanie, że OpenGL może (w zasadzie) robić to, co chce, może nawet spekulować bufor nad PCIe spekulacyjnie, zanim jeszcze narysujesz. Działa to, ponieważ nie jesteś właścicielem danych (OpenGL robi to!) I możesz uzyskać do nich dostęp tylko za pośrednictwem danego interfejsu API, więc zawsze wiadomo, że dane są prawidłowe. Sterownik może nawet wyrzucić pamięć bufora na kartę graficzną, gdy potrzebuje pamięci na coś innego, a później przywrócić ją z tajnej kopii, jeśli zajdzie taka potrzeba.
  3. To naprawdę głupie mylące określenie, dla którego znacznie lepszą nazwą byłoby coś takiego jak zestaw buforów lub zestaw deskryptorów, to niesławny obiekt tablicy wierzchołków . Z twojego punktu widzenia jest to tylko zestaw uchwytów buforowych zebranych razem pod innym niejasnym uchwytem (który możesz powiązać). Tak się składa, że ​​rzeczywistość jest nieco bardziej skomplikowana. W rzeczywistości VAO jest znacznie bliżej tego, jak działa rzeczywisty sprzęt. Karty graficzne mają niewielką liczbę (często coś w rodzaju 2, 4 lub 8) zestawów deskryptorów (nie tylko dla buforów, ale także dla samplerów) z tak dużą liczbą wpisów w każdym, pomiędzy którymi mogą bardzo skutecznie przełączać się .
    Teraz celem obiektu tablicy wierzchołków jest zmniejszenie liczby wywołań API i zmniejszenie liczby kontroli spójności, które OpenGL musi wykonać wewnętrznie, i oczywiście, aby używać sprzętu tak, jak działa. Jeśli powiążesz 5 buforów, każdy musi przejść niektóre potencjalnie drogie kontrole, a każdy z nich jest kandydatem na brak pamięci podręcznej w sterowniku, a ponadto każdy z nich wymaga komunikacji z kartą graficzną w celu zmiany deskryptora itp. Jeśli zamiast tego po powiązaniu jednego VAO sterownik może (często) po prostu przełączyć zestaw deskryptorów na karcie graficznej i gotowe.
Damon
źródło
8

Obiekt tablicy wierzchołków (VAO) to obiekt, który zawiera jeden lub więcej obiektów bufora wierzchołków i jest przeznaczony do przechowywania informacji o pełnym renderowanym obiekcie.

(wyciągnął z Khronos )

Każdy bufor zwykle stanowi jeden atrybut tablicy wierzchołków (obiektu). VAO może zawierać wiele atrybutów wierzchołków (np. Pozycja, kolor, UV). Każdy z nich może być przechowywany w swoim własnym buforze, gdzie bufor wskazuje niesformatowaną serię ciągłych bajtów, i gdzie musisz jawnie określić rozmiar (typ) dla elementu bufora zarówno dla wywołań OpenGL po stronie procesora, jak i działania modułu cieniującego po stronie GPU.

To jest jeden sposób. Inne sposoby to może działać:

  • Wszystkie atrybuty są przechowywane przeplatane w jednym buforze LUB
  • Niektóre atrybuty istnieją we własnych dedykowanych buforach, podczas gdy inne współużytkują bufory.

Poniższy schemat ilustruje te dwa ostatnie przypadki.

wprowadź opis zdjęcia tutaj

Konkluzja: Jeśli wyrażenie „tablica wierzchołków” zostanie użyte w OpenGL bez zastrzeżeń, możesz założyć, że oznacza ono VAO, co w kontekście OpenGL (konkretnie) jest czymś zupełnie innym niż bufor.

EDYTUJ swój komentarz: GL_ARRAY_BUFFERwskazuje zamiar użycia tego obiektu bufora dla danych atrybutów wierzchołków, jak opisano powyżej. Jest tak, ponieważ bufory nie są używane tylko dla atrybutów wierzchołków. Ponieważ jednak jest to najczęstszy przypadek użycia i pytasz o VAO, nie będę wchodził w inne; tutaj jednak znajduje się lista innych typów buforów, które można skonfigurować.

Inżynier
źródło
Więc bufory są: 1.reside w GPU, 2.most czasu zawierać jeden rodzaj danych (tylko wierzchołek, kolor tylko ect), 3.Data jest przeplatana, czyli 111122223333 ect. 4. nie podają żadnej metody dostępu do danych (nie bufora [2] ani bufora [vertex_3434]). Tablice to: 1. kolekcja buforów, 2. przechowywanie informacji o tym, jak parsować bufory, które ona zawiera. , rozmiar elementu, przesunięcia, aby dane z buforów były dostępne poprawnie, prawda?
coobit
1. Bufory istnieją na obu końcach i przesyłają między CPU a GPU (potencjalnie do tyłu i do przodu), w przeciwnym razie, jak byś wypełnił dane, które mają być przesłane do GPU podczas ładowania siatki z dysku ?. Tak, elementy są tego samego typu w całym buforze, ale w zależności od używanej technologii każdy element bufora może być pierwotny lub structtypowy. Dane mogą być przeplatane lub być całkowicie jednorodne na bufor. Możesz się do nich indeksować, podobnie jak w tradycyjnej macierzy C na CPU. Szykuj obiekty (użyj tej poprawnej terminologii lub skończyć się myleniem!) ... (ciąg dalszy poniżej)
Inżynier
2. Tak i musisz wyraźnie upewnić się, że deklaracje bufora modułu cieniującego będą zgodne ze specyfikacjami ustawionymi w VAO po stronie procesora: „Wszystkie stany związane z definicją danych używanych przez procesor wierzchołków są zawarte w wierzchołku obiekt tablicy ”. (khronos docs)
Inżynier
Więc po prostu uderzyć w paznokieć więcej ... Jak ludzie pracowali przed AO tylko za pomocą BO? Czy AO zawsze był obecny w OpenGL i to tylko VAO, które zostało wprowadzone później niż VBO?
coobit
@coobit io7m.com/documents/history-vertex-spec - daje to wyobrażenie o różnicach między ustalonym potokiem (stara szkoła) OpenGL, 3Dfx itp. a nowoczesnym, programowalnym potokiem OpenGL i Direct3D.
Inżynier
5

Ta terminologia jest zakorzeniona w historii OpenGL. Ważne jest, aby pamiętać, że dla większości wersji GL, które są tutaj istotne, OpenGL ewoluował stopniowo i poprzez dodanie nowej funkcjonalności do już istniejącego API zamiast zmiany API.

Pierwsza wersja OpenGL nie miała żadnego z tych typów obiektów. Rysowanie zostało osiągnięte poprzez wydanie wielu wywołań glBegin / glEnd, a jednym problemem z tym modelem było to, że był on bardzo nieefektywny pod względem narzutu wywołania funkcji.

OpenGL 1.1 podjął pierwsze kroki, aby rozwiązać ten problem, wprowadzając tablice wierzchołków. Zamiast bezpośrednio określać dane wierzchołków, możesz je teraz pozyskiwać z tablic C / C ++ - stąd nazwa. Tak więc tablica wierzchołków jest właśnie taka - tablica wierzchołków i stan GL wymagany do ich określenia.

Kolejna ważna ewolucja przyszła z GL 1.5 i pozwoliła na przechowywanie danych tablicy wierzchołków w pamięci GPU, a nie w pamięci systemowej („po stronie klienta”). Słabością specyfikacji tablicy wierzchołków GL 1.1 było to, że pełny zestaw danych wierzchołków musiał być przesyłany do GPU za każdym razem, gdy chciałeś z niego korzystać; jeśli był już na GPU, można tego transferu uniknąć i osiągnąć potencjalny wzrost wydajności.

Tak więc utworzono nowy typ obiektu GL, aby umożliwić przechowywanie tych danych na GPU. Podobnie jak obiekt tekstury służy do przechowywania danych tekstury, obiekt bufora wierzchołków przechowuje dane wierzchołków. W rzeczywistości jest to tylko szczególny przypadek bardziej ogólnego typu obiektu bufora, który może przechowywać nieswoiste dane.

Interfejs API do używania obiektów bufora wierzchołków został oparty na istniejącym już interfejsie API tablic wierzchołków, dlatego widzisz takie dziwne rzeczy, jak konwertowanie przesunięć bajtów na wskaźniki. Mamy teraz interfejs API tablic wierzchołków, który po prostu przechowuje stan, przy czym dane pochodzą z obiektów buforowych, a nie z tablic w pamięci.

To prowadzi nas prawie do końca naszej historii. Wynikowy interfejs API był dość gadatliwy, jeśli chodzi o określanie stanu tablicy wierzchołków, więc inną drogą optymalizacji było stworzenie nowego typu obiektu, który zgromadziłby cały ten stan razem, pozwolił na wiele zmian stanu tablicy wierzchołków w jednym wywołaniu API i pozwolił na GPU potencjalnie przeprowadzić optymalizacje ze względu na to, że z góry wiadomo, jaki stan będzie wykorzystany.

Wprowadź obiekt tablicy wierzchołków, który zbiera to wszystko razem.

Podsumowując, tablica wierzchołków rozpoczęła życie jako zbiór stanów i danych (przechowywanych w tablicy) do rysowania. Bufor wierzchołek zastępuje pamięci tablicy w pamięci z obiektów typu GL pozostawiając szereg wierzchołków prostu stanem. Obiekt tablicy wierzchołków jest po prostu obiektem kontenerowym dla tego stanu, umożliwiając jego łatwiejszą zmianę i mniej wywołań API.

Maximus Minimus
źródło
0

Od jakiegoś czasu nie pracowałem z OpenGL, więc mogę mieć tylko połowę racji. Ogólnie rzecz biorąc: bufory przechowują tablicę niesformatowanej pamięci. Tablica to ogólny termin ciągłej pamięci.

Bufor musi być powiązany z kontekstem, podczas gdy tablica jest tylko tablicą danych. Jeśli dobrze pamiętam, dane w buforze mają zostać skopiowane na kartę graficzną (stąd powiązanie).

Mam nadzieję, że to trochę pomoże

Juicef
źródło
Czym jest GL_ARRAY_BUFFER? Dlaczego tak się nazywa? Według twojej hipotezy jest to „Niesformatowana pamięć ciągła” :)
coobit
Cóż, ten konkretny przykład jest tylko identyfikatorem bufora (z którym wiążesz tablicę). Bufor tablic (w twoim przykładzie) jest używany dla atrybutów wierzchołków, więc w zasadzie powiązujesz tablicę atrybutów wierzchołków z buforem. Brzmi myląco, więc dam ci przykład. Po stronie procesora masz tablicę, która może być kolorowa, normalna, pozycje itp., A teraz chcesz, aby GPU miała do niej dostęp. To właśnie wtedy, gdy pojawia się bindBuffer, w zasadzie mapowanie „tablicy cpu” na „tablicę gpu”.
Juicef
Nie mogę odpowiedzieć na pytanie, dlaczego tak się nazywa. Zakładam, że dzieje się tak dlatego, że masz tam szereg różnych danych, kolorów, normalności itp.
Juicef