Mají u mě velké plus, že se (aspoň na první pohled) dokázali zbavit kontextu v globální proměnné (případně thread-safe) jako v původním OpenGL.
Na druhé straně ještě jeden krok navíc to chtělo - místo globálních funkcí v knihovně udělat jasný interface se sadou virtuálních metod nebo pointerů na metody, pokud bychom se museli bavit o plain C.
Takhle z toho bude opět neskutečný bordel jako v temných časech OpenGL, s nejasnými pravidly kam by měl zasahovat vendor specific driver, jak řešit různé knihovny od různých vendorů na stejné mašině (on CPU vs dedicated), v takových případech nejspíš další zbytečný layer navíc atd.
Pokud chcete trochu komplexnejší API které půjde portovat i do jiných jazyků než C++ a i na jiné systémy tak pak bohužel C je nejlepší. Naštěstí lidi z Nvidia napsali podobný wrapper na C++ jako u OpenCL i pro Vulkán (https://developer.nvidia.com/open-source-vulkan-c-api). V tomhle je Vulkan daleko před OpenGL
To C jim až tak moc (z praktických důvodů) neberu, ale i v C se dá přece implementovat Factory pattern a interface. Viz drivery v linuxovém kernelu, případně v user space ncurses, které jsou snad sto let staré. Chápu, že v 80/90-tých letech byl u designu OpenGL předpoklad, že dodavatel systému je dodavatel hardwaru a se skřípěním zubů se jedna /usr/lib/libgl.so dala pochopit. Ale dneska, kdy každý druhý desktop má dvě grafiky, které se navíc v runtime střídají?!?
Ohledně linku na initialization-functionpointers - jo, takhle to některé aplikace dělaly už v OpenGL, ale je to drbání pravou rukou a levým uchem. Taky v zásadě řeší stejně jen část abstrakce - co když bude mít vendor pro různé účely různé implementace command queue?
A viz OpenGL - ve výsledku stejně většina aplikací přímo linkuje libgl.so, takže řešení bude místo vendor-specific libvulkan.so naimplementovat wrapper, který bude v zásadě vytvářet další wrapper pro každé "createObject" volání a virtualizovat funkce nad ním...
Ten C++ wrapper od Nvidia, jestli dobře vidím, neřeší problém přes abstraktní driver, pouze zapouzdřuje jednotlivé volání do metod objektů (či spíše struktur)...
Vulkan bych strukturou k GL vůbec nepřirovnával. Problém verzí, vendorů a layerů reší přímo loader: https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/sdk-1.0.3/loader/LoaderAndLayerInterface.md
Navíc to na jakých GPU, s jakou verzí Vulkanu, s jakými vrstvami řeší přímo aplikace.
Ten Nvida wrapper měl být argument na plain C style.
Ten loader je bohužel přesně to, co jsem popisoval. Místo, aby skutečně zajistil pouze discovery a load vendor driveru, tak pronásleduje (intercepting) každé další volání, které už má jít přímo do driveru - viz obrázek na druhé a třetí stránce :-/ Zcela zbytečný overhead a navíc řešení polovičaté...
Kdyby volání šlo přímo do driveru, tak by API přišlo o podporu vrstev pro debug, tracing... a všechny aplikace by to musely bastlit samy (skoro nic by se tím neušetřilo). Ano overhead tam je ale malý v porovnáním co všechno se u renderingu dělá aby se vykreslila scéna. Bež těchto důležitých features, by se to ve Vulkanu velmi těžko vyvíjelo.
To si nemyslím, spíš právě naopak. Bavíme se samozřejmě o user space vrstvě toho driveru. Pokud budu chtít další funkcionalitu kolem, jednoduše zabalím (v případě potřeby!) do proxy. Získám tak prakticky to samé, co mi umožní zmíněný Vulkan loader, ale daleko flexibilnější a neomezený tím, co vývojář toho "oficiálního" loaderu považoval za důležité.
Ten overhead, co tam je, není v celém kontextu možná velký, ale primárně zbytečný. Nehledě na to, že vendor bude mít nejspíš rovněž potřebu vnitřní abstrakce, takže si tyhle function pointery wrapne do podobné virtualizace. Overhead roste a nic nepřináší, naopak komplikuje.
V zásadě správně to měl vyřešené Direct3D už snad před dvaceti lety, nutno dodat, že jej rovnou postavili nad COM, pro kterou je takové řešení přirozené. Nicméně viz výše, ani v C to není nijak velkou překážkou...
Funkcionalitu kolem budu potřebovat ve všech případech, protože bez debug/validation layeru se ve Vulkanu neda pracovat, takže by to implementovali opravdu všichni a stejně by nakonec na github vznikla knihovna která by dělala skoro to stejné, a importovali by ji úplně všichni. Takže nechť ať to naimplementujou lidi z LunarG/Khronos/Nvidia/AMD/Qualcomm.., kteří do toho vidí mnohem líp než komunita.
Navíc princip vrstev které se sypou do loaderu je "univerzální", takže místo abych patlal nejaký svůj standard (ala svoje vlastní proxy), tak bude přenositelnější (pro více projektů) to implementovat jako layer.
COM model není taky bez overheadu a taky bychom se mohli začít hádat jeslti je zbytečný a nešlo by skoro to stejné naimplementovat "lépe"/bez některých featur, a navíc jeho implementace v C by byla velká a řekněme zbytečná šílenost, která by na výkonu ušetřila/přidala "nic".
Ten loader může samozřejmě obsahovat běžně používané proxy, ale pořád ta možnost volby zajistí flexibilitu, lepší performance a lepší abstrakci. Nacpat to tam natvrdo přes globální funkce nic nepřinese a je to omezující. Jestli by vznikla knihovna, která by implementovala běžné funkce - proč ne? Ale pořád má ten vendor možnost volby a když přijde s lepší hardwarovou implementací, tak ji může snadno nahradit. To není ten případ, pokud Vulkan bude část řešit na horní vrstvě. Což si ani nemyslím, bo primární cíl je mít skutečně low-level přístup.
Ad Direct3D/COM - to byl jen příklad korektního abstraktního řešení. Samotný COM je zde samozřejmě kanón na vrabce, ten princip je loadnout vendor shared library, a vrátit pointer na VkDevice strukturu, která bude mít v sobě pointery na waitIdle, destroyDevice, getDeviceQueue, a opět VkQueue se submit, bindSparse atd. Na to nepotřebuju žádný overhead...