Come funziona OpenGL al livello più basso? [chiuso]


85

Capisco come scrivere programmi OpenGL / DirectX, e conosco la matematica e le cose concettuali che ci stanno dietro, ma sono curioso di come la comunicazione GPU-CPU funzioni a basso livello.

Supponiamo che io abbia un programma OpenGL scritto in C che visualizza un triangolo e ruota la telecamera di 45 gradi. Quando compilo questo programma, sarà trasformato in una serie di chiamate ioctl, e il driver della gpu invia quindi i comandi appropriati alla gpu, dove è cablata tutta la logica della rotazione del triangolo e dell'impostazione dei pixel appropriati nel colore appropriato in? O il programma verrà compilato in un "programma gpu" che viene caricato sulla gpu e calcola la rotazione, ecc.? O qualcosa di completamente diverso?

Modifica : pochi giorni dopo ho trovato questa serie di articoli, che sostanzialmente risponde alla domanda: http://fgiesen.wordpress.com/2011/07/01/a-trip-through-the-graphics-pipeline-2011-part- 1 /


La specifica OpenGL afferma che i comandi vengono inviati in modalità client / server. La specifica è troppo ampia per determinare una tecnologia specifica utilizzata dalle implementazioni OpenGL.
Luca

Risposte:


87

È quasi impossibile rispondere a questa domanda perché OpenGL di per sé è solo un'API front-end, e fintanto che un'implementazione aderisce alle specifiche e il risultato è conforme a questo, può essere fatto come preferisci.

La domanda potrebbe essere stata: come funziona un driver OpenGL al livello più basso. Ora è di nuovo impossibile rispondere a questo in generale, poiché un driver è strettamente legato a qualche componente hardware, il che potrebbe di nuovo fare le cose comunque lo sviluppatore lo ha progettato.

Quindi la domanda avrebbe dovuto essere: "Come appare in media dietro le quinte di OpenGL e del sistema grafico?". Diamo un'occhiata a questo dal basso verso l'alto:

  1. Al livello più basso c'è un dispositivo grafico. Oggigiorno si tratta di GPU che forniscono un set di registri che controllano il loro funzionamento (che registra esattamente dipende dal dispositivo) hanno una memoria di programma per shader, memoria di massa per i dati di input (vertici, texture, ecc.) E un canale I / O per il resto del sistema su cui riceve / invia dati e flussi di comandi.

  2. Il driver grafico tiene traccia dello stato delle GPU e di tutti i programmi applicativi delle risorse che fanno uso della GPU. Inoltre è responsabile della conversione o di qualsiasi altra elaborazione dei dati inviati dalle applicazioni (converte le texture nel formato pixel supportato dalla GPU, compila gli shader nel codice macchina della GPU). Inoltre fornisce un'interfaccia astratta dipendente dal driver per i programmi applicativi.

  3. Poi c'è la libreria / driver client OpenGL dipendente dal driver. Su Windows questo viene caricato dal proxy tramite opengl32.dll, sui sistemi Unix risiede in due posti:

    • Modulo GLX X11 e driver GLX dipendente dal driver
    • e /usr/lib/libGL.so può contenere alcune cose dipendenti dal driver per il rendering diretto

    Su MacOS X questo sembra essere "OpenGL Framework".

    È questa parte che traduce le chiamate OpenGL come lo fai in chiamate alle funzioni specifiche del driver nella parte del driver descritta in (2).

  4. Infine l'attuale libreria API OpenGL, opengl32.dll in Windows e su Unix /usr/lib/libGL.so; questo per lo più passa solo i comandi all'implementazione OpenGL corretta.

Il modo in cui avviene la comunicazione effettiva non può essere generalizzato:

In Unix la connessione 3 <-> 4 può avvenire o tramite Socket (sì, può, e va in rete se lo si desidera) o tramite Shared Memory. In Windows la libreria dell'interfaccia e il client del driver vengono entrambi caricati nello spazio degli indirizzi del processo, quindi non c'è molta comunicazione ma semplici chiamate di funzione e passaggio di variabili / puntatori. In MacOS X questo è simile a Windows, solo che non c'è separazione tra l'interfaccia OpenGL e il client del driver (questo è il motivo per cui MacOS X è così lento a tenere il passo con le nuove versioni di OpenGL, richiede sempre un aggiornamento completo del sistema operativo per fornire il nuovo struttura).

La comunicazione tra 3 <-> 2 può passare attraverso ioctl, lettura / scrittura o mappare parte della memoria nello spazio degli indirizzi del processo e configurare la MMU per attivare un codice driver ogni volta che vengono apportate modifiche a quella memoria. Questo è abbastanza simile su qualsiasi sistema operativo poiché devi sempre oltrepassare il confine kernel / userland: alla fine passi attraverso un po 'di syscall.

La comunicazione tra il sistema e la GPU avviene attraverso il bus perifiale e i metodi di accesso che definisce, quindi PCI, AGP, PCI-E, ecc., Che funzionano tramite Port-I / O, Memory Mapped I / O, DMA, IRQ.


1
Questa descrizione è probabilmente di livello troppo basso e generica con pochissime specifiche OpenGL. Si applica all'incirca a qualsiasi componente hardware presente in un computer.
v.shashenko

1
@ v.shashenko: Beh, ovviamente. Indipendentemente dal componente hardware con cui stai parlando, segue questo schema generale. Ma OpenGL non è un particolare software, è solo una specifica e tutto ciò che è conforme alla specifica è un'implementazione valida. E poiché alla fine un'implementazione OpenGL sta parlando con una GPU, seguirà più o meno lo stesso script lungo il quale vengono implementate le API che affrontano l'hardware. È impossibile diventare più specifici di così, perché non esiste l' implementazione " The ONE " di OpenGL. E ogni implementazione è leggermente diversa.
datenwolf

1
@ v.shashenko: Se desideri maggiori dettagli, dovresti chiedere informazioni su un'implementazione particolare. Ad esempio, dire X11 + GLX + DRI → Mesa / AMDGPU → Linux-KMS + DRM (Direct Rendering Manager). E ognuno di questi componenti è una bestia piuttosto complessa con così tanti dettagli, che potresti riempire i libri con i dettagli su come funziona ogni componente. Ma questo descriverebbe l'implementazione di Linux-AMDGPU. Ma Linux + NVidia è una bestia completamente diversa. E su Windows è di nuovo diverso.
datenwolf

Ti ricordi di me abbiamo chattato per lunghi giorni fa, volevo solo sapere come contattarti nel caso volessi sapere qualcosa.?
Suraj Jain,

Quello che hai insegnato quel giorno, ha chiarito molti dei miei dubbi, ne ha fatto anche uno nuovo, ma nel complesso ora non considero una magia disegnare finestre e icone sullo schermo.
Suraj Jain

23

Quando compilo questo programma, sarà trasformato in una serie di chiamate ioctl, e il driver della gpu invia quindi i comandi appropriati alla gpu, dove è cablata tutta la logica della rotazione del triangolo e dell'impostazione dei pixel appropriati nel colore appropriato in? O il programma verrà compilato in un "programma gpu" che viene caricato sulla gpu e calcola la rotazione, ecc.?

Non sei lontano. Il programma chiama il driver client installabile (che non è realmente un driver, è una libreria condivisa nello spazio utente). Ciò utilizzerà ioctl o un meccanismo simile per passare i dati al driver del kernel.

Per la parte successiva, dipende dall'hardware. Le schede video più vecchie avevano quella che viene chiamata "pipeline a funzione fissa". C'erano spazi di memoria dedicati nella scheda video per le matrici e hardware dedicato per la ricerca di texture, la fusione, ecc. Il driver video caricava i dati e i flag corretti per ciascuna di queste unità e quindi impostava DMA per trasferire i dati dei vertici (posizione , colore, coordinate della trama, ecc.).

L'hardware più recente ha core del processore ("shader") all'interno della scheda video, che differiscono dalla CPU in quanto ognuno di essi funziona molto più lentamente, ma ce ne sono molti altri che lavorano in parallelo. Per queste schede video, il driver prepara i binari del programma da eseguire sugli shader GPU.


20

Il tuo programma non è compilato per nessuna GPU particolare; è solo collegato dinamicamente a una libreria che implementerà OpenGL. L'implementazione effettiva potrebbe comportare l'invio di comandi OpenGL alla GPU, l'esecuzione di fallback del software, la compilazione di shader e l'invio alla GPU o persino l'utilizzo di fallback shader ai comandi OpenGL. Il panorama grafico è abbastanza complicato. Per fortuna il collegamento ti isola dalla maggior parte della complessità dei driver, lasciando gli implementatori di driver liberi di utilizzare qualsiasi tecnica ritengano opportuno.


18

I compilatori / linker C / C ++ fanno esattamente una cosa: convertono i file di testo in una serie di codici operativi specifici della macchina che vengono eseguiti sulla CPU. OpenGL e Direct3D sono solo API C / C ++; non possono convertire magicamente il compilatore / linker C / C ++ in un compilatore / linker per la GPU.

Ogni riga di codice C / C ++ che scrivi verrà eseguita sulla CPU. Le chiamate a OpenGL / Direct3D chiameranno le librerie C / C ++, statiche o dinamiche a seconda dei casi.

L'unico posto in cui un "programma gpu" entra in gioco è se il codice crea esplicitamente shader. Cioè, se effettui le chiamate API in OpenGL / D3D che causano la compilazione e il collegamento di shader. Per fare ciò, tu (in fase di runtime, non in fase di compilazione C / C ++) generi o carichi stringhe che rappresentano shader in alcuni linguaggi shader. Quindi li sposti attraverso il compilatore dello shader e ottieni un oggetto in quell'API che rappresenta quello shader. Quindi applicare uno o più shader a un particolare comando di rendering. Ognuno di questi passaggi avviene in modo esplicito nella direzione del codice C / C ++, che come affermato in precedenza viene eseguito sulla CPU.

Molti linguaggi shader utilizzano la sintassi simile a C / C ++. Ma questo non li rende equivalenti a C / C ++.


Ho imparato l'opengl negli ultimi tempi e mi sono chiesto perché vedo tutti questi "programmi shader" nel codice che guardo scritti come stringhe letterali. Come hai detto, vengono compilati in fase di esecuzione. Ho visto alcuni esempi in alcuni codici di Android opengl es. Poi ho visto del codice anche per iPhone. Apparentemente l'iPhone ha quattro processori vettoriali in grado di eseguire calcoli in virgola mobile molto più velocemente di quanto possa fare la CPU dell'iPhone, quindi puoi scrivere l'ASM come stringhe letterali da compilare in fase di esecuzione per utilizzare quei processori invece della CPU principale.
eggie5

1
La maggior parte della "pipeline di funzioni fisse" è ora implementata da un set predefinito di programmi shader. Non è necessario richiedere esplicitamente uno shader per ottenerne uno.
Ben Voigt

1
@ Ben Voigt: Vero, ma se nessuno te lo dicesse, non saresti in grado di capire la differenza.
Nicol Bolas

1
Che potrebbe essere un atteggiamento ragionevole da assumere, se questa domanda non riguardasse i dettagli nascosti.
Ben Voigt
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.