Skąd mam wiedzieć, że zbyt mocno abstrakuję interfejsy API grafiki?


23

Tworząc renderer, który obsługuje wiele interfejsów API grafiki, zwykle chcesz wyodrębnić kod w jakiejś bibliotece niskiego poziomu, która jest powiązana z niektórymi interfejsami API grafiki, takimi jak OpenGL, Vulkan, D3D11 i tak dalej;

Działają one bardzo odmiennie, dlatego tworzenie dobrego ogólnego API staje się niezbędne; Czytałem, że zwykle chciałbyś użyć „zaplecza”, który implementuje podstawową funkcjonalność dla każdego interfejsu API, który chcesz obsługiwać, oraz „interfejsu”, który jest używany przez programistę do rysowania rzeczy na ekran.

Skąd mam wiedzieć, czy robię zbyt ciasną abstrakcję?


5
Czy masz 100% pewności, że Twoje opakowanie + Vulkan lub D3D11 jest szybsze niż zwykłe korzystanie z OpenGL?
Mooing Duck

@Mooing Duck, jeśli jest używany prawidłowo, tak.
Gabriele Vierti,

4
Poważnie w to wątpię. Większość korzyści w Vulkan pochodzi z bardzo niskiego poziomu i robienia rzeczy w bardzo szczególny, specyficzny sposób. Coś, co jest wystarczająco ogólne, aby zrobić to samo bezproblemowo w OpenGL lub D3D, prawie na pewno nie może tego zrobić. Reimplementacja tych samych rzeczy, co robi OpenGL (jak robi to wiele samouczków Vulkan, jak na ironię) daje 99,99% tej samej wydajności przy 20-krotnym nakładzie pracy.
Damon,

@Damon to prawda, ale nowsze API są specjalnie zaprojektowane (i nie przystosowane jak OpenGL) do pracy w nowoczesnych procesorów graficznych; Mówiąc o Vulkan, można dość dużo korzystają z tego samego interfejsu API na każdej obsługiwanej platformie, w przeciwieństwie do OpenGL, gdzie trzeba użyć „Embedded Systems” wersję. Poza mniejszym obciążeniem procesora i fantazyjnymi funkcjami nie mamy wiele, ale w przyszłości możemy mieć dość zaskakujące techniki, które mogą działać szybciej przy użyciu Vk lub D3D12 zamiast OGL lub D3D11
Gabriele Vierti

Odpowiedzi:


44

Przede wszystkim zastanów się, czy naprawdę warto obsługiwać więcej niż jeden graficzny interfejs API. Samo użycie OpenGL obejmie większość platform i będzie „wystarczająco dobre” dla wszystkich oprócz najbardziej ambitnych graficznie projektów. O ile nie pracujesz dla bardzo dużego studia gier, które może pozwolić sobie na zatopienie kilku tysięcy osobogodzin we wdrażaniu i testowaniu wielu backendów renderujących i chyba że są jakieś funkcje specyficzne dla DirectX lub Vulcan, które naprawdę chcesz się pochwalić, zwykle nie jest to warte kłopotu . Zwłaszcza biorąc pod uwagę, że możesz zaoszczędzić dużo pracy, używając warstwy abstrakcji stworzonej przez kogoś innego (biblioteka innej firmy lub silnik gry).

Ale załóżmy, że już oceniłeś swoje opcje i doszedłeś do wniosku, że jest to opłacalne i warte czasu, aby rzucić własne.

Zatem głównym sędzią architektury oprogramowania twojej warstwy abstrakcji są twoi programiści.

  • Czy są w stanie zaimplementować systemy gier, które chcą wdrożyć, nie zastanawiając się nad szczegółami niskiego poziomu?
  • Czy są w stanie całkowicie zignorować, że istnieje więcej niż jeden interfejs graficzny API?
  • Czy teoretycznie byłoby możliwe dodanie kolejnego backendu renderującego bez zmiany jakiegokolwiek kodu front-end?

Jeśli tak, to ci się udało.


2
Jedna dodatkowa sugestia: czy warto podkreślić, że celem jest osiągnięcie celów w punktorach przy minimalnym wysiłku - po prostu trafić w cel i nie iść dalej? W przeciwnym razie każdy z nich może zmienić się w króliczą dziurę dla typowego dewelopera, który (w tym ja) często nie wie, kiedy zostawić wystarczająco dobrego w spokoju. :) A także, że jedynym niezawodnym sposobem oceny sukcesu jest iteracyjne opracowanie i przetestowanie interfejsu API z rzeczywistymi użytkownikami; nie da się dokładnie zgadnąć, co prowadzi do scenariusza nadmiernej inżynierii.
Bob

5
Dodałbym, że jeśli naprawdę musisz obsługiwać wiele bibliotek graficznych, prawie na pewno jest taka gotowa, która robi wszystko, czego potrzebujesz, więc nawet wtedy naprawdę nie powinieneś tworzyć własnych. (Oczywiście są wyjątki, ale jeśli nie masz wystarczającego doświadczenia, aby zapytać „jak ścisła jest abstrakcja”, prawdopodobnie nie pracujesz nad projektem, który wymaga tego)
pozew fundacji Moniki z

Nie jestem grafikiem, ale patrząc na ramy kompatybilności z historii baz danych i systemów operacyjnych, dodam, że prawie na pewno nie warto tworzyć własnych ogólnych ram. Framework prawie na pewno będzie musiał poświęcić wydajność dla kompatybilności, co prawdopodobnie oznacza, że ​​i tak nie możesz wiele zrobić z tymi specjalistycznymi funkcjami. Istniejące ramy są prawie pewne, że lepiej poradzą sobie z tymi problemami ze względu na szersze zastosowanie. Teraz, jeśli masz ogromny opisany budżet i chcesz zbudować wyspecjalizowane ramy (na przykład dla jednej gry lub serii), może to być bardziej wykonalne.
jpmc26,

6

Zacznij od określenia, czego potrzebujesz w części „otoki” interfejsu API. Zasadniczo jest to bardzo, bardzo proste: potrzebujesz podstawowych zasobów (buforów, shaderów, tekstur, stanu potoku) i sposobu na wykorzystanie tych zasobów do zbudowania ramki przez przesłanie niektórych wywołań losowania.

Staraj się trzymać logikę wysokiego poziomu z dala od opakowania API. Jeśli zaimplementujesz sprytną technikę przerywania sceny w tej części interfejsu API, teraz masz problem z powieleniem tej logiki we wszystkich implementacjach zaplecza. To dużo dodatkowego wysiłku, więc zachowaj prostotę. Zarządzanie scenami powinno być częścią wyższego poziomu interfejsu API, który używa opakowania, a nie częścią samego opakowania.

Wybierz cele, które będziesz wspierać i zrozum je. Trudno jest napisać przyzwoite opakowanie dla „wszystkiego” i prawdopodobnie nie musisz (prawdopodobnie nie musisz pisać ani jednego opakowania, jak zauważono w odpowiedzi Filipa ). Prawie niemożliwe jest napisanie przyzwoitego opakowania, jeśli nie znasz już interfejsów API, które zamierzasz zawinąć.

Regularnie oceniaj stan swojego interfejsu API. Zasadniczo powinien mieć mniejszą powierzchnię niż leżące u podstaw owinięte API; jeśli odkryjesz, że tworzysz typy opakowań jeden do jednego dla każdej struktury D3D lub każdego wywołania funkcji OpenGL, prawdopodobnie zboczysz z kursu.

Spójrz na to, co już minęło. Sokol i BGFX to interfejsy API, które zapewniają poziomy agnostycyzmu, które mogą być przydatne i stosunkowo łatwe do zrozumienia (szczególnie te pierwsze).


3

Kolejną kwestią, o której jeszcze nie wspomniano, którą należy wziąć pod uwagę, są cele dotyczące wydajności. Jeśli Twoim celem jest posiadanie biblioteki graficznej, która zapewni dobrą wydajność dzięki taniej platformie sprzętowej, ale będzie również użyteczna na różnych platformach, które są znacznie bardziej wydajne, ale używają innego interfejsu API, warto zaprojektować interfejs API wszelkie abstrakty są używane natywnie na platformie, na której wydajność jest problemem. Nawet jeśli powoduje to obniżenie prędkości o 50% na bardziej wydajnych platformach, może być tego warte, jeśli pozwala na zwiększenie prędkości o 20% na platformie, na której wydajność ma największe znaczenie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.