Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: Some multithreading questions

  1. #1
    Junior Member Regular Contributor
    Join Date
    Jun 2003
    Posts
    121

    Some multithreading questions

    I had thought that I understood threading and OpenGL, but I seem to be experiencing some multithreaded bugs and its made me question myself. Perhaps they are just driver issues because I'm off the beaten video game path. I wanted to sort of play a true/false game to check if my understanding agrees with everyone. Also I'm more interested in what is the best practice (that will help me avoid driver quirks rather than what the GL specification says which is somewhat incomplete with regards to multithreading shared contexts imo).

    1) If contextA is current to threadA and contextB is current to threadB and the contexts have been previously shared, do we have to worry about thread protection/mutexes? I'd assume that in the driver contextA and contextB share a table of textures and furthermore since OpenGL is not thread safe then we need explicit protection for modification of existing objects and whenever creating/destroying objects:
    (a) to prevent threadA and threadB from modifying the same object at once and
    (b) to handle the case where the texture table could be modified simultaneously by multiple threads at once. eg. suppose contextA creates a new texture ID and the driver decides it needs to grow the shared texture table data structure whilst at the same time contextB is attempting to bind a texture from the very same table

    2) If I have shared contextA and contextB and now wish to delete just contextB but continue to use contextA then its safe to delete it, but both must be not current (or just no OpenGL operations must occur on contextA during wglDeleteContext?).

    3) If I create contextA and contextB on the same thread then they must be shared on that same thread or the driver may become upset.

    4) If I want to share contextA and contextB they must be created on the same thread or the driver may become upset. Said differently: you shouldn't share contexts that were created on different threads.

    5) It is not required but it is the best practice to share your new context before you create any GL objects on it. ie. always share new empty context with existing context

    6) It is not required but it is the best practice to have one hub context (that you never use except to share contexts with) which all other contexts share themselves with

  2. #2
    Member Regular Contributor
    Join Date
    Jan 2005
    Location
    USA
    Posts
    411
    I am busy right now but there is a current thread all about multithread (http://www.opengl.org/discussion_boa...ltiple-threads) that you might find insightful. Will check back here later...
    God have mercy on the soul that wanted hard decimal points and pure ctor conversion in GLSL.

  3. #3
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    1) The OpenGL 4.3 specification has an entire section on objects and multiple contexts (and thus threads). In particular, you need to prevent 1a, but 1b should be fine. That is, you can create different object names and object instances in different threads. The creation is, for all intents and purposes, atomic.

    2) If you're deleting contextB, contextA does not care. You do need to make sure contextB isn't current, but that's about it.

    3)

    If I create contextA and contextB on the same thread then they must be shared on that same thread or the driver may become upset.
    Perhaps, but one would hope that you're using wgl/glXCreateContexAttribARB(), which specifies that the newly created context will be shared with another at creation time.

    4) No idea.

    5)

    It is not required but it is the best practice to share your new context before you create any GL objects on it. ie. always share new empty context with existing context
    It is required. For example, wglShareLists states:

    Quote Originally Posted by MSDN
    Specifies the OpenGL rendering context to share display lists with hglrc1. The hglrc2 parameter should not contain any existing display lists when wglShareLists is called.
    If we extend this to all shared objects, then the new context must not have created any shareable objects. Again, wgl/glXCreateContextAttribsARB creates and shares contexts; use that where possible.

    6) That's up to you. However you want to manage your contexts, objects, etc is your prerogative. If you want to keep a phantom context around just to keep objects alive, you can do that.

    Such a thing might be useful for dealing with window re-creation (such as when resizing the desktop or some-such) without destroying every OpenGL object.

  4. #4
    Junior Member Regular Contributor
    Join Date
    Dec 2000
    Location
    Madrid, Spain
    Posts
    136
    Hi Stephen_H
    I have two threads: one loading thread and one render thread.

    At the beginning of the program, I create two render contexts in one of the threads (render thread in this case):
    Code :
    ///--- OpenGL 2.1
    int attributes[] = {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 2,
        WGL_CONTEXT_MINOR_VERSION_ARB, 1,
        WGL_CONTEXT_FLAGS_ARB, 0,
        0
        };
    HGLRC rcGL21=wglCreateContextAttribsARB(hDC, NULL, attributes);
    if(rcGL21!=NULL){
        g_hRTRC=rcGL3x;
        g_hMTRC=wglCreateContextAttribsARB(hDC, NULL, attributes);
        if(g_hMTRC==NULL){
            ... Error
        }
    }
     else{
       ... Error
    }
     
    if(!wglShareLists(g_hMTRC, g_hRTRC)){
       ... Error
    }
    if(!wglMakeCurrent(hDC, g_hRTRC)){
       ... Error
    }

    And after that in the other thread:
    Code :
    if(!wglMakeCurrent(hDC, g_hMTRC)){
       ... Error
    }

    And everything works properly. The only thing I have noticed is that you cannot call to glTexImage2D at the same time in the two threads. But if you use one thread to create/load 'objects' (textures, framebuffers, ...) and the other to render, everything works properly.

    Hope this helps.

  5. #5
    Junior Member Regular Contributor Kopelrativ's Avatar
    Join Date
    Apr 2011
    Posts
    214
    Quote Originally Posted by Stephen_H View Post
    Also I'm more interested in what is the best practice
    I think the best practice is to not use multi threading for OpenGL. That is, only one thread is needed to keep the graphics card busy too 100%, and so you can't gain any FPS by using more than one thread.

    Of course, you can still use threads to prepare data that will be used. A good way to design this is to use some kind of thread pool.

  6. #6
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    433
    If you're trying to optimize texture transfers, you could check out this presentation by NVidia. Or the slides here(PDF)

Posting Permissions

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