Come faccio a sapere se sto astraggendo le API grafiche troppo strettamente?


23

Quando si crea un renderer che supporta più API grafiche, in genere si desidera astrarre il codice in una sorta di libreria di basso livello collegata ad alcune API grafiche come OpenGL, Vulkan, D3D11 e così via;

Funzionano in modo molto diverso l'uno dall'altro, quindi diventa essenziale una buona API generica; Ho letto che in genere si desidera utilizzare un "back-end" che implementa le funzionalità di base per ciascuna API che si desidera supportare e un "front-end" che è ciò che viene utilizzato dal programmatore per disegnare elementi sul schermo.

Come faccio a sapere se sto facendo un'astrazione troppo stretta?


5
Sei sicuro al 100% che il tuo wrapper + Vulkan o D3D11 sia più veloce del semplice utilizzo di OpenGL?
Mooing Duck,

@Mooing Duck se usato correttamente, sì.
Gabriele Vierti,

4
Ne dubiterei seriamente. La maggior parte dei guadagni di Vulkan deriva dall'essere di livello molto basso e dal fare le cose in un modo molto particolare e specifico. Qualcosa che è abbastanza generico per fare altrettanto senza problemi in OpenGL o D3D quasi certamente non può farlo. La reimplementazione delle stesse cose di OpenGL (come fanno molti tutorial di Vulkan, ironicamente) porta al 99,99% delle stesse prestazioni, con 20 volte il lavoro.
Damon,

@Damon è vero, ma le API più recenti sono progettate specificamente (e non adattate come OpenGL) per funzionare su gpus moderno; parlando di Vulkan, puoi praticamente usare la stessa API su ogni piattaforma supportata, al contrario di OpenGL, dove devi usare la versione "Sistemi integrati". A parte meno sovraccarico della CPU e funzionalità fantasiose non abbiamo molto, ma in futuro potremmo avere alcune tecniche piuttosto sorprendenti che potrebbero funzionare più velocemente usando Vk o D3D12 piuttosto che OGL o D3D11
Gabriele Vierti,

Risposte:


44

Prima di tutto, considera se vale davvero la pena supportare più di un'API grafica. Il solo utilizzo di OpenGL coprirà la maggior parte delle piattaforme e sarà "abbastanza buono" per tutti tranne i progetti graficamente più ambiziosi. A meno che tu non lavori per uno studio di gioco molto grande che può permettersi di affondare diverse migliaia di ore-persona nell'implementazione e nel test di più backend di rendering e a meno che non ci siano alcune funzionalità specifiche di DirectX o Vulcan che vuoi davvero sfoggiare, di solito non vale la seccatura . Soprattutto se si considera che è possibile risparmiare molto lavoro utilizzando un livello di astrazione creato da qualcun altro (una libreria di terze parti o un motore di gioco).

Ma supponiamo che tu abbia già valutato le tue opzioni e sei giunto alla conclusione che è fattibile e vale la pena dedicare il tempo alle tue.

Quindi il giudice principale dell'architettura software del tuo livello di astrazione sono i tuoi programmatori front-end.

  • Sono in grado di implementare i sistemi di gioco che vogliono implementare senza doversi meravigliare di dettagli di basso livello?
  • Sono in grado di ignorare completamente che esiste più di un'API grafica?
  • In teoria sarebbe possibile aggiungere un altro backend di rendering senza modificare il codice front-end?

Se è così, ci sei riuscito.


2
Un ulteriore suggerimento: vale la pena sottolineare che l'obiettivo è quello di raggiungere gli obiettivi nei punti elenco con il minimo livello di sforzo - solo per raggiungere l'obiettivo e non andare oltre? Altrimenti ognuna di queste può trasformarsi in una tana di coniglio per lo sviluppatore tipico che (me compreso) spesso non sa quando lasciare abbastanza buono da solo. :) E anche che l'unico modo affidabile per giudicare il successo è sviluppare e testare l'API in modo iterativo con gli utenti reali ; è impossibile indovinarlo con precisione e porta a uno scenario da buca di coniglio di ingegneria eccessiva.
bob

5
Vorrei aggiungere che, se davvero si ha per supportare le librerie grafiche multiple, c'è quasi sicuramente un off-the-shelf uno che fa tutto il necessario per, quindi, anche allora davvero non si deve rotolare il proprio. (Certo, ci sono delle eccezioni, ma se sei abbastanza inesperto da chiederti "quanto dovrei fare un'astrazione" probabilmente non stai lavorando a un progetto che ti richiede di farlo)
Fund Monica's Lawsuit

Non sono uno sviluppatore grafico, ma guardando i framework di compatibilità dalla storia di database e sistemi operativi, aggiungerei che quasi sicuramente non ne vale la pena per creare il tuo framework generale . Il framework dovrà quasi certamente sacrificare le prestazioni per la compatibilità, il che probabilmente significa che non puoi fare molto con quelle funzionalità specializzate comunque. I quadri esistenti sono quasi certi di gestire meglio questi problemi a causa di un uso più ampio. Ora, se hai l'enorme budget che descrivi e vuoi costruire un framework specializzato (diciamo per un gioco o una serie), potrebbe essere più fattibile.
jpmc26,

6

Inizia identificando ciò di cui hai effettivamente bisogno dalla parte "wrapper" dell'API. In genere è molto, molto semplice: sono necessarie le risorse di base (buffer, shader, trame, stato della pipeline) e un modo per utilizzare tali risorse per costruire un frame inviando alcune chiamate di disegno.

Cerca di mantenere qualsiasi logica di alto livello fuori dalla porzione wrapper dell'API. Se implementate una tecnica di abbattimento delle scene intelligente in questa parte dell'API, ora siete pronti a duplicare quella logica in tutte le implementazioni di backend. È un grande sforzo, quindi è semplice. La gestione delle scene dovrebbe far parte di una parte di livello superiore dell'API che utilizza il wrapper anziché far parte del wrapper stesso.

Scegli gli obiettivi che sosterrai e comprendili. È difficile scrivere wrapper decenti per "tutto", e probabilmente non è necessario (probabilmente non è nemmeno necessario scrivere un singolo wrapper, come indicato nella risposta di Philipp ). È quasi impossibile scrivere un wrapper decente se non si conoscono le API che si stanno già avvolgendo.

Valuta regolarmente lo stato della tua API. In generale, dovrebbe avere una superficie inferiore rispetto alle API con wrapping sottostanti; se ti ritrovi a creare tipi di wrapper one-to-one per ogni struttura D3D o ogni chiamata di funzione OpenGL probabilmente stai andando fuori rotta.

Guarda che lavoro è stato fatto prima. Sokol e BGFX sono API che forniscono livelli di agnosticismo che potrebbero esserti utili e sono relativamente facili da capire (il primo in particolare).


3

Un altro punto non ancora menzionato che dovresti considerare è quali sono i tuoi obiettivi prestazionali. Se il tuo obiettivo è avere una libreria grafica che fornisca buone prestazioni da una piattaforma hardware economica, ma sia anche utilizzabile su una varietà di piattaforme che sono enormemente più potenti ma utilizzano un'API diversa, può avere senso progettare la tua API in base qualunque astrazione venga utilizzata nativamente sulla piattaforma in cui le prestazioni sono un problema. Anche se ciò causa un degrado della velocità del 50% sulle piattaforme più potenti, può valerne la pena se consente un miglioramento della velocità del 20% sulla piattaforma dove le prestazioni contano di più.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.