Multithreading Rendering in OpenGL

Ho un’applicazione con multithreading, in cui sto cercando di rendere con diversi thread. Prima ho provato ad usare lo stesso Contesto di Rendering tra tutti i thread, ma mi è stato sempre NULL contesti attuali per altri thread. Ho letto su internet che un contesto può essere solo la corrente di un thread alla volta.

Così ho deciso di fare qualcosa di diverso. Ho creato una finestra, ho l’HDC da esso e creare la prima RC. Dopo di che, io condividere questo HDC tra i thread, e in ogni nuovo thread che ho creato posso ottenere un nuovo RC dallo stesso HDC e la faccio attuale per quel thread. Ogni volta che lo faccio, la RC restituito è sempre diverso (di solito il valore precedente + 1). Faccio un’affermazione per verificare se wglGetCurrentContext() restituisce un RC, e sembra che restituisce quello che è stato appena creato. Ma dopo aver fatto il rendering, non ottengo nessun rendering e se chiamo GetLastError() ottenere errore 6 (handle non valido??)

Questo significa che, al di là di ogni nuova chiamata di wglCreateContext() mi dà un nuovo valore, in qualche modo, ciò significa che tutti questi valori sono gli stessi “canale di Collegamento” per le chiamate di OpenGL?

Questo significa che dovrò sempre valido il precedente Contesto di Rendering su un thread, e attivare la nuova? Devo davvero fare questo per la sincronizzazione di tutti i tempi, o c’è qualche altro modo di lavorare intorno a questo problema?

  • googled 2 pagine, che potrebbero aiutare: higherorderfun.com/blog/2011/05/26/… e opengl.org/discussion_boards/showthread.php/…
  • beh, io sto facendo qualcosa di molto simile a questo, ma io sto Errore 6 dopo wglShareLists chiamata
  • Penso che la questione dovrebbe anche leggere come “Dal multithreading DirectX 11 di rendering è più veloce di un singolo thread, il driver di portare la stessa miglioramenti da OpenGL chiamate così ?”
InformationsquelleAutor filipehd | 2012-06-19



4 Replies
  1. 46

    Ho un’applicazione con multithreading, in cui sto cercando di rendere con diversi thread.

    NON!!!

    Si otterrà nulla dal tentativo di multithread il renderer. Fondamentalmente si sta eseguendo una condizione di competizione e il driver sarà solo impegnato la sincronizzazione di thread in qualche modo dare un senso di esso.

    Per ottenere migliori prestazioni di rendering di tenere tutte le operazioni OpenGL per un solo thread. Tutti parallelizzazione accade per libero sulla GPU.

    • Ok io non esprimermi correttamente. Non significa che sarà il rendering sullo schermo. In realtà essi non. Un thread attinge il backbuffer, e copia il suo contenuto in una texture. L’altro semplicemente “Blits” la Texture sullo schermo. Significa che il thread può eseguire il rendering su backbuffer altri complessi di cose.
    • “Un thread attinge il backbuffer, e copia il suo contenuto in una texture. L’altro semplicemente “Blits” la Texture sullo schermo.” Whyy? Non basta scambiare la parte posteriore e anteriore del buffer quando si vuole presentare?
    • Anche allora utilizzando più thread non ha senso. Il “blitter” filo d’attesa per il “renderer” filo alla fine. Il punto di multithreading è quello di mantenere le cose funzionano contemporaneamente; che non.
    • Anche se voi ragazzi sono di destra, non risponde alla mia domanda del perché faccio 6 di errore dopo wglShareLists(). Ancora, significa che per fare quello che voglio ho bisogno di auxiliar buffer come OSA o PBuffer?
    • No, perché io non lo swapping il buffer, ma solo una copia per la trama molto piccola parte dello schermo che è stato modificato. Quindi, se devo cambiare un quadrato 10×10 px, io sono solo la copia di questa porzione di texture e rendering texture su schermo. Non c’è bisogno di RIDISEGNARE l’intera scena di nuovo
    • Perché la creazione di un nuovo contesto per ogni nuovo thread, comunque? RCs non sono vincolati al contesto in cui sono stati creati con. | Perché sei costantemente la creazione di un nuovo thread? Hanno solo un singolo thread e inviare code di lavoro per processo. Google per “thread pooling”
    • perché ho letto in diversi posti che condividono la stessa RC tra i thread non è una buona pratica e di non sicuro. Ecco perché ho deciso di creare una RC per ogni thread.
    • Beh, la condivisione (cioè con il contesto di essere attivo in più thread contemporaneamente) un contesto che non è possibile, ma passando da filo a filo è possibile. Tuttavia, Si dovrebbe evitare di ri-creazione di thread e contesti per tutto il tempo. Creare un pool di thread esattamente una volta e bastone ad esso. Stesso per i contesti, anche se io consiglio vivamente contro l’utilizzo di più contesti diversi thread. Sono uno dedicato OpenGL thread, le cose si fanno molto più facile, e anche più performante in quel modo.
    • Alla fine, è come l’esecuzione di più applicazioni OpenGL sulla stessa GPU. Non è così male come sembra la tua risposta: non è il driver in grado di pipeline multiple contesto di operazioni?
    • Con la distinzione sottile, che processi separati, di solito, il rendering di controller di dominio separato. Tuttavia OP ha più thread destreggiarsi circa i dati da un comune RC. Sì, si può fare, ma perché preoccuparsi?
    • Sto cercando qualcosa di simile a OP. In sostanza, viene utilizzato un thread per nulla UI relative, che hanno bisogno di una costante di tempo di un comportamento (per la risposta UI) e un thread per l’elaborazione di immagini e di calcolo. È solo il MODO più facile per passare una texture ref (che è un GLuint) che per assicurarsi che non stai accesso ai dati dell’immagine nel thread dell’interfaccia utente, mentre è scritto da immagine thread di elaborazione, che potrebbe causare funky immagini del rendering.
    • Ho lavorato su parecchi giochi in cui più di rendering sono stati in esecuzione su più thread. Per esempio un gioco di corse dove l’esterno in avanti, retrovisori (per gli specchi) e HUD sono stati tutti disegnati sul loro thread e poi composte in vista presentato al lettore. Questo non è un irrealistico cosa fare.
    • Cosa API grafiche questi giochi utilizzano? OpenGL usato per avere (ancora) un certo fama di essere schizzinoso quando si tratta di multithreading. Se hai fatto tutto bene, quindi sì, più di rendering thread potrebbe colpire il fast path. Ma ci vuole un sacco di profilatura per ottenere questo diritto.
    • “tenere tutte le operazioni OpenGL per un solo thread” Questo non è del tutto vero, si dovrebbe tenere tutte le operazioni di RENDERING di un thread. Se è vero che nessun beneficio deriva in termini di esecuzione, non ci sono motivi per avere buffer funzioni in esecuzione in altri thread per la struttura del codice. Per esempio, un produttore di creazione dei thread e stroring dati in VBOs per il rendering. Non con la GL funzioni del produttore thread porta a codice più complicato.
    • So cosa pensate, BT;DT. Mentre dovrebbe funzionare in teoria (e la maggior parte del tempo), è incline ad esporre brutto driver bug, infatti proprio ora sto eseguendo il debug di un’applicazione che fa un po ‘ di pioggia inter-thread buffer di aggiornamenti, anche in via di elaborazione, e il modo in cui le texture sono dinamicamente ridimensionata innesca un bug il blocca disco rigido del driver (è necessario riavviare il sistema per fissarla). Per quello che ne vale la pena se si desidera aggiornare OpenGL buffer da un thread separato, creare e mappare il buffer di oggetti GL thread, quindi inviare il lavoratore messaggio che l’indirizzo a cui scrivere.

  2. 14

    Suggerisco di leggere il seguente articolo della wiki da OpenGL Consorzio.

    http://www.opengl.org/wiki/OpenGL_and_multithreading

    In parole semplici, dipende molto su che cosa si intende per il multi threading quanto riguarda OpenGl, se si dispone di un thread che fa il rendering parte e uno (o più) a fare altri lavori (cioè l’IA, la Fisica, la logica di gioco, ecc), non è perfettamente diritto.

    Se si desidera avere più thread rovinare con OpenGL, non è possibile, o meglio, si potrebbe, ma sarà davvero dare più problemi che vantaggi.

    Prova a leggere le FAQ sul parallelo OpenGL utilizzo, per avere una migliore idea su questo concetto:

    http://www.equalizergraphics.com/documentation/parallelOpenGLFAQ.html

    • ma è proprio questa la mia idea di applicazione – Diversi thread prendersi cura di logica diversa – Quello che non capisco è perchè sto ricevendo un errore di 6 dopo la chiamata wglShareLists. Forse sto chiamando questa funzione è troppo tardi? Cercherò di usare l’idea scritto il primo link che mi hai dato per verificare come funziona.
    • Logica diversa mezzi diversi sottosistemi. Un thread per le reti, una per l’utente di input, uno per tutto OpenGL, etc. Davvero, non cercare di diffondere la grafica uscita su più thread. Si tratta di un pasticcio enorme. Anche il “blitting operazione” (disegno a trama quad), che tutto l’overhead di passare a un altro thread possa causare più tempo consumato, che l’attuale “dalla”. Anche la GPU è una esclusiva di risorse, non è possibile avere più thread di utilizzare la GPU allo stesso tempo, in modo che il blitter filo d’attesa per qualsiasi altra operazione sulla GPU per finire in ogni caso.
    • non so, ma così mi dice che, per esempio, in un gioco complesso, ogni singolo pixel rendering della scena è reso sempre sullo STESSO thread? Non hanno mai di utilizzare più thread per migliorare le prestazioni di rendering?
    • Questo è davvero il caso. Perché si tenta di multithread il rendering comandi comunque? La parallelizzazione accade sulla GPU, che richiede una grande serie di primitive geometriche, processi in parallelo (vertex shader), determina la coperta di frammenti e di processi di frammenti in parallelo (fragment shader).
    • Ora pensate a cosa succederebbe se effettivamente inviato due lotti di primitive geometriche per la GPU in parallelo: Si andrebbe a finire in una condizione di competizione, perché entrambi avrebbero (molto probabile) tocca lo stesso frammenti. Questa è una condizione di competizione che può essere risolta solo con la sincronizzazione dei due lotti, che bancarelle la pipeline di elaborazione, provocando un grave calo di prestazioni.
    • Anche tutti importante motore di gioco esistente farà tutto il possibile per mantenere tutti i renderer di operazioni non in un solo thread, ma anche sullo stesso core della CPU. Fare tutto in un solo thread per evitare di driver bug (non conosco i driver OpenGL a tutti, che non hanno un qualche tipo di problemi di multithreading; solo di recente NVidia aveva alcuni). E mantenere le cose su un core è quello di migliorare la cache località.
    • vi ringrazio molto per le informazioni. Ti il 100% di senso quello che stai dicendo.
    • FAQ link è una pagina vuota.

  3. 5

    In alcuni casi può essere utile utilizzare più di rendering contesti in diversi thread. Ho usato un design per caricare i dati dell’immagine da filesystem e spingere questi dati in una texture.

    • Sarebbe meglio caricare le texture (non OpenGL roba) in un altro thread e quindi aggiornare la texture nel thread che possiede il contesto.
    • Pensi contesto di condivisione rallenta il driver GL? Aggiornamento delle texture è una delle funzioni che consumano la maggior parte del tempo, quindi imho si fa questo in thread separato consente di risparmiare un sacco di tempo nel thread principale. Certo che è valida solo per i dati che non è necessario immediatamente.
    • Inoltre ho implementato texture streaming una volta. Contesto di condivisione è davvero male se si utilizza il contesto da più thread contemporaneamente. Ma io non sono come veloce è quando hai la garanzia di non utilizzare MAI contemporaneamente. Non credo che sarebbe lento. Ma se funziona, allora funziona. Btw: Se avete bisogno di asincrono texture caricare, utilizzare i pbo.
    • “Ma io non sono SICURO di* come veloce è” non vedi che errore…
    • Sono d’accordo, quando cercando su diverse piattaforme, la prestazione non è stata buona in tutti loro. Sono d’accordo anche che è adatto solo per i dati che vengono visualizzate in anteprima sfondo e non utilizzate in attivo thread di rendering.
    • Vedo… Quando l’ho implementato texture streaming (tramite pre-mip maps), che in streaming migliaia di texture. Ho usato i pbo per che. La performance è stata abbastanza buona. Tutti i dati sono stati caricati in un secondo thread, ma caricato nel renderer thread. Vorrei andare con qualcosa di simile.

  4. 0

    OpenGL su Mac OS X è single-thread-safe; per attivarlo:

    #include <OpenGL/OpenGL.h>
    
    CGLError err = 0;
    CGLContextObj ctx = CGLGetCurrentContext();
    
    //Enable the multi-threading
    err =  CGLEnable( ctx, kCGLCEMPEngine);
    
    if (err != kCGLNoError ) {
         //Multi-threaded execution is possibly not available
         //Insert your code to take appropriate action
    }

    Vedere:
    Concorrenza e OpenGL – Apple Developer

    E:
    Tecnico Q&A QA1612: OpenGL ES multithreading e …

    • Perché il voto si / no?
    • La domanda è su Windows. Non elencati in tag, ma HDC e GetLastError rendono evidente.
    • Se si utilizza Windows persona… io non sono… Plus OS estensioni specifiche spesso non è nel non-specifiche del sistema operativo GL rilascio.

Lascia un commento