Question about GPU-CPU Sync, also unrelated question about multithreading

I have heard that there are particular commands that force the gpu to sync with the client thread

What are they?

And my question about multithreading (Same thread b/c I don’t want to spam)

If I have decide to create a thread off the main thread, and it makes OpenGL draw calls, and it is the only one making draw calls for the duration of that time, will it work?

Diagram:

Main thread
(Does some OpenGL calls)

  • Splits into three threads*
    Thread 1: Does OpenGL calls
    Thread 2: does something unrelated
    Thread 3: does something unrelated
    Main Thread: does something unrelated
  • Threads join *
    (OpenGL calls)
    Threads split again
    … repeat

Diagram in MS Paint:
https://kek.gg/i/4szZKP.png

[QUOTE=Geklmin;1291153]I have heard that there are particular commands that force the gpu to sync with the client thread

What are they?
[/QUOTE]
Anything which returns data back to client memory has to wait until that data actually exists, which may require some or all preceding commands to complete.

Anything which takes data from client memory and overwrites data in GPU memory either has to wait until any command using the existing data has completed or must make a temporary copy. It’s up to the implementation as to which happens.

Essentially, any OpenGL function which takes a pointer specifies when data is read from or written to the memory referenced the pointer. In most cases it’s before the function returns, so if the transfer cannot be performed immediately the function must block until it can be performed. The exception is client-side vertex arrays, which are read during draw calls.

Any thread making OpenGL calls must have a context bound. A given context can only be bound in one thread at a time. If you use a single context, you need to unbind it from the first thread before binding it in the second. If you use multiple contexts, you need to ensure each is set up correctly and either they need to share data (buffers, textures, etc) or you need to create the objects for each context. When contexts share data, container objects (e.g. FBOs, VAOs) aren’t shared; they need to be created and managed for each context.

[QUOTE=GClements;1291163]
Any thread making OpenGL calls must have a context bound. A given context can only be bound in one thread at a time. If you use a single context, you need to unbind it from the first thread before binding it in the second.[/QUOTE]

How do I do that?

I’m using GLFW and GL3W to manage opengl contexts and extensions.

[QUOTE=Geklmin;1291166]How do I do that?

I’m using GLFW and GL3W to manage opengl contexts and extensions.[/QUOTE]
Use glfwMakeContextCurrent() to bind a window and its associated contextand to the current thread.

Using multiple contexts isn’t going to be feasible with GLFW, as it doesn’t allow you to create and manage contexts separately from windows. If you just want to load data in a separate thread, you can create a hidden window and use the context associated with it; but you can’t have two different contexts and use both to render to the same window.

[QUOTE=Geklmin;1291153]I have heard that there are particular commands that force the gpu to sync with the client thread
What are they?[/QUOTE]

It’s worth adding to the above tips that some GL drivers will actually “tell” you when they’re having to synchronize internally (because of the way you’re using openGL) …if you ask them to. NVidia’s GL driver is one of these.

You do that by registering a message callback in a GL context with debug support enabled. It’s easy.

See this page for details:

[ul]
[li]Debug Output (OpenGL Wiki) [/li][/ul]
The Examples section at the bottom has some copy/paste code to get you going.

This is generally true. For instance, glMapBuffer() or glMapBufferRange (without special flags) is one that surprises many folks. However, it’s worth noting that glMapBufferRange() with the GL_MAP_UNSYNCHRONIZED flag explicitly bypasses the need for the driver to block the CPU or ghost (make a temp copy of) the data. Read more about it here: Buffer Object Streaming. Persistent maps are another method which can be used to bypass traditional MapBuffer’s synchronization.

Thanks, Dark Photon!

You’re #1