Short version:
Never use shared contexts for performance-conscious code, it costs way more than the failed (more on that later) overlap of the texture uploads.
Long version:
During early development of a major product (Steam Big Picture Mode) in the past that used multiple contexts for background uploading of OpenGL textures, we were told by multiple desktop GPU vendors
that the drivers flatly mutex every OpenGL call when you have shared contexts, this can result in major (~20%) fps loss even if you don’t use the other context at all, it gets worse if you do, and in
particular the texture upload does NOT happen in parallel with rendering due to that mutexing.
So my advice is never do this, we changed the product to not do this before launch because it was completely not performant, we had been struggling to keep up 60fps until we did, then it easily
exceeded 200fps with that one change.
The hitching of texture uploads is pretty much unavoidable in OpenGL ES (iOS, Android, etc), on desktop OpenGL you can somewhat hide it with GL_ARB_pixel_buffer_object - where you glMapBuffer on the
main thread and then write the pixels from another thread, when done you glUnmapBuffer on the main thread and then issue the glTexImage2D with the pixel buffer object bound, so that it sources its
pixels from that object rather than blocking on a client memory copy, but I’m sure this isn’t free and I have not tried it in practice, it also requires that you more or less queue your uploads for
the main thread to prepare in stages so that’s some lovely ping-pong there.
While I too would greatly appreciate the addition of some background object upload functionality in OpenGL, or even an entire deferred command buffer system (I proposed this in a hardware-agnostic way
but it didn’t gain traction), the reality today is that OpenGL contexts and threading are completely non-viable.
I should note that Doom 3 BFG Edition seems to use a glMapBuffer on each of 3 buffer objects (vertex, index, uniforms) at the beginning of the frame, queue jobs for all of the processing it wants to
do, so that threads write into those mapped buffers, and then at end of frame it does the glUnmapBuffer and walks its own command list to issue all the real GL calls that depend on that data - this
works very well, but is out of the scope of most OpenGL threading discussions.On 01/16/2014 06:29 AM, slimshader wrote:
Stefanos A. wrote:
This should work, provided your GPU drivers can do context sharing without going belly up. (This includes first-gen Atoms with PowerVR IGPs and some Core / Core2 mobile IGPs with old drivers.)
MonoGame does the exact same thing and it appears to be working fine.
That said, why do you need two OpenGL contexts?
2014/1/14 godlike <>
Quote:
Hi all,
In the game engine that I am working on, I am designing a rendering thread that essentially executes all OpenGL calls (including SDL_GL_SwapWindow) instead of the main thread. The problem is that I am
not quite sure if the scenario that I have in mind is something safe or it will lead to undefined behavior.
The idea is that in the main thread will:
Code:
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS | …);
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); // Enable context sharing
window = SDL_CreateWindow(…);
context_A = SDL_GL_CreateContext(window); // Create context A
context_B = SDL_GL_CreateContext(window); // Create context B
SDL_GL_MakeCurrent(window, context_A); // Make context A current
start_rendering_thread()
// Game loop begins
while(true) {
poll_input_and_joystick_events_using_SDL()
do_other_things()
}
In the rendering thread:
Code:
SDL_GL_MakeCurrent(window, context_B); // Make context B current
while(true) {
execute_GL_calls()
SDL_GL_SwapWindow(window);
}
The thing that bugs me is that I am calling SDL_GL_SwapWindow(window) in another thread and that I am doing some SDL stuff in the main thread and others in the rendering thread (polling events).
What do are your thoughts? Will this work or not?
Panagiotis Christopoulos Charitos
AnKi 3D Engine http://www.anki3d.org/
SDL mailing list
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
I had no problems with 2 contexts on Windows and Mac but I got crashes on iOS. I used 2nd GL context to upload textures in the background, while main thread was doing the rendering. I disabled
background uploding (and 2nd ctx) in the end on iOS, didn’t have enoych time to investigate
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
–
LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier