Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 19

Thread: Creating objects in another thread

  1. #1
    Junior Member Newbie
    Join Date
    Oct 2013
    Posts
    13

    Creating objects in another thread

    I'm trying to use another thread for creating (and loading) OpenGL objects
    The problem is that I have a successful D3D implementation, as it supports threaded object creation.

    As for OpenGL , I have followed the guideline described here, and also using GLFW3 for managing contexts:
    • At Init, I Create the main context and set it after other contexts and threads are created
    • At Init I create a context (new 1x1 hidden window in GLFW) for loader thread, in the main thread, Also I pass the main thread's context to loader thread as shared
    • At the start of loader thread execution, set it to current
    • Create my objects in the loader thread
    • After loading done, pass the object IDs and render them in main thread


    But I'm currently having couple of problems, that I need to ask ...
    • Besides Buffers and texture objects, I'm creating VAOs, I've read somewhere that VAO's can't be shared, as a result I don't get valid geometry, is this true?
    • Performance is terrible, when I create another context shared with the main one, I get terrible frame-rates, for example from 3-4ms per-frame to 20ms per-frame (using latest AMD gpu drivers), any tips? or is there anything wrong with this method of loading ?
    Last edited by septag; 01-20-2014 at 11:15 AM.

  2. #2
    Senior Member OpenGL Pro Aleksandar's Avatar
    Join Date
    Jul 2009
    Posts
    1,146
    Before going any further, let's clear some facts:

    1. The web page you are referencing to is not very clear and a little bit deprecated. I'm surprised Alfonse didn't correct it.

    2. During GL context creation you should define sharing group.

    3. If you have multiple contexts, make each one current in a separate thread (and don't "pass" them to other threads, as you mention in the post).

    4. You don't need VAO to fill VBO with data (loading thread should be confined just to that). And, yes, VAOs are not shared among contexts.

    5. After all, having resource loading in a separate GL context (not thread) you probably won't get any performance boost, since GL contexts are not really "parallel". It is easier for implementation to have monolithic gigantic VBOs loaded at once in a separate thread, instead of splitting it into slices and loaded in the drawing thread, by thus far my experience is that the second approach is actually faster because don't require synchronization. So, multi-threading - yes, but multi-context - maybe...

  3. #3
    Junior Member Newbie
    Join Date
    Oct 2013
    Posts
    13
    thx for the early reply
    2. what do you mean by sharing group? I just send the main context to the "shared" parameter for proceeding contexts, and call wglShareList in windows, after all it's glfw that does all the work

    3. maybe I didn't explain properly, I just create contexts in the main thread, but set them to current in their own threads

    4. yes I know, but I'm creating the whole high level object (model for example) and it's gl objects in another thread, thought I could get away with vao's too, like what I'm doing with the d3d impl.

    5. I'm implementing background loading of game resources like models and textures. The performance problem I was talking about occurs only when I create additional context for another thread, even if I do nothing with it. and the slowdown is HUGE. could it be because I'm creating 2nd context with a dummy hidden window? (that' the only way glfw let's me create contexts)

  4. #4
    Senior Member OpenGL Pro Aleksandar's Avatar
    Join Date
    Jul 2009
    Posts
    1,146
    Quote Originally Posted by septag View Post
    2. what do you mean by sharing group? I just send the main context to the "shared" parameter for proceeding contexts, and call wglShareList in windows, after all it's glfw that does all the work
    That's exactly I meant with the sharing group (passing the first context as the second parameter of the wglCreateContextAttribsARB for the others). But, do not use wglShareList! That's the implicit meaning of my first statement. It is a remnant of the "ancient" time. Using wglCreateContextAttribsARB is sufficient.

    Quote Originally Posted by septag View Post
    3. maybe I didn't explain properly, I just create contexts in the main thread, but set them to current in their own threads
    That's also correct.

    Quote Originally Posted by septag View Post
    4. yes I know, but I'm creating the whole high level object (model for example) and it's gl objects in another thread, thought I could get away with vao's too, like what I'm doing with the d3d impl.
    This part I don't understand. What do you call a "gl object"?

    Quote Originally Posted by septag View Post
    5. I'm implementing background loading of game resources like models and textures. The performance problem I was talking about occurs only when I create additional context for another thread, even if I do nothing with it. and the slowdown is HUGE. could it be because I'm creating 2nd context with a dummy hidden window? (that' the only way glfw let's me create contexts)
    Didn't you say you're creating (all) contexts at the start? Or I just assumed that?
    You shouldn't create contexts during application execution.
    Second, you don't need new windows to create other contexts!
    Window is required for setting pixel format. It should be done only once for the drawing window. All contexts in the sharing group should have the same pixel format so there is nothing to do with the windows. I've never used glfw. Maybe you are right about that constraint, but check it again since it is not the constraint of the OpenGL itself.

  5. #5
    Junior Member Newbie
    Join Date
    Oct 2013
    Posts
    13
    This part I don't understand. What do you call a "gl object"?
    GL objects are like GL textures, VBOs, etc...

    Didn't you say you're creating (all) contexts at the start? Or I just assumed that?
    You shouldn't create contexts during application execution.
    Yes, I don't create contexts during execution, not that crazy

    Second, you don't need new windows to create other contexts!
    Unfortunately, I was limited to GLFW, and GLFW doesn't let me create contexts individually, they have to be created with their window.
    But today I forked it and followed the guideline described here to create my own custom GL contexts (no new window, just get the DC of the main window)

    Managed to resolve the VAOs also by creating them in the main thread.
    But the major problem still persists, which is the horrible performance when I'm trying to create VBOs using another context.
    Here's a shot, that I disabled the whole multi-threaded loading feature:


    And here's a second shot, with mult-threaded loading (thus another context) turned on:


    Check out the ft (frame time) graph, as you can see, muti-threaded object creation doesn't just raise spikes, It continues to slows down the performance drastically through all frames. But in D3D implementation and also no-background loading, it's all good.

    So I currently don't know if it's a drivers fault (someone experienced this with AMD drivers/GPU?) or something I did wrong with the GL api

    There is no resource leaking, there is no resource recreation, because I have abstracted the API layers, all higher-level logic is same with D3D/GL
    - Worker (loader) context is created in main thread
    - Worker context is set to current in the loader thread
    - glFlush() is called after loading (VBO/texture creation) in the loader thread
    - No window is created for worker context, I just get the DC from main window and create it
    - worker context is not using any draw functions, just common glGen, glBind, glBufferData, ...
    - worker context is using main context as shared parameter upon creation
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	gl-without-mtload.jpg 
Views:	75 
Size:	12.6 KB 
ID:	1216   Click image for larger version. 

Name:	gl-with-mtload.jpg 
Views:	78 
Size:	11.5 KB 
ID:	1217  
    Last edited by septag; 01-21-2014 at 10:01 AM.

  6. #6
    Senior Member OpenGL Pro Aleksandar's Avatar
    Join Date
    Jul 2009
    Posts
    1,146
    It is hard to say what the problem is. Does the frame rendering time stays high even after the loading process or just during the loading?
    How do you measure frame rendering time? Is it a GPU or a CPU time? How do you communicate between threads? You should use sync objects for context synchronization. They are part of the core since GL 3.2. That will not change performance, but should assure the object is finished before accessing from the other thread/context.

  7. #7
    Junior Member Newbie
    Join Date
    Oct 2013
    Posts
    13
    Does the frame rendering time stays high even after the loading process or just during the loading?
    Yes, I also noticed that even if I load resource in the main thread (using the main context), I get the same slowdown, just because I've created another context that is shared with the current one!

    Is it a GPU or a CPU time?
    CPU time

    I guess the problem is with the AMD drivers!
    I upgraded from catalyst 13.9 to 13.12 today, and saw major improvement in frame-rates, currently with 13.12 the cpu frame-time graph is like this:
    Click image for larger version. 

Name:	gl-13.12.png 
Views:	57 
Size:	2.4 KB 
ID:	1218

    It's still not very stable like with no secondary context, but far better than 13.9 drivers

    for comparison, this is Direct3D result of multi-threaded loading, look how stable the fps is:
    Click image for larger version. 

Name:	d3d-mtload.png 
Views:	59 
Size:	2.1 KB 
ID:	1219
    Last edited by septag; 01-22-2014 at 04:08 AM.

  8. #8
    Senior Member OpenGL Pro Aleksandar's Avatar
    Join Date
    Jul 2009
    Posts
    1,146
    Then I hope the case is closed.

  9. #9
    Junior Member Newbie
    Join Date
    Oct 2013
    Posts
    13
    Posted a similiar post on AMD developer's forum, to see if they got an answer.
    Overall I had many problems with AMD's OpenGL drivers till now, they don't seem to be polished at all.

  10. #10
    Member Regular Contributor
    Join Date
    Apr 2004
    Posts
    251
    personally i've had bad experience with shared contexts and came to conclusion that they are to be avoided when possible.
    generally they are not used very often by the developers and so the driver writers tend to overlook them so that when using shared contexts you are more likely to stumble on driver bugs.
    Also they have inherent performance penalty because the driver is forced to use some kind of mutexes to avoid messing between threads, which is not the case in non-shared mode.
    It may be better if you re-organize your software as to avoid using shared contexts.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •