OpenGL and Multithreading

Hi! I'll try to be short.

I'm making my OpenGL application multithreaded, because I want to load resources (models, textures, shaders and fonts) asynchronously, without blocking the application (the main thread).

Resource management works, but my texture is not passed to my compute shader.
I don't know why. If I load my texture on the main thread, it works, but not in the other thread.

This works:
Image * img = new Image("noiseTex1");
noiseTex[0] = Texture::CreateTexture(img);
delete img;

This does not work:
ResourceManager::RequestResource(new QueueElement(std::string("noiseTex1"), &noiseTex[0]));

The method RequestResource adds the requested resource to a std::queue, protected with mutexes, which will be iterated by the other thread which loads resources.
So, essentially this method does the working code written above, after checking if it has been already loaded or not.

I can confirm the texture is loaded. I can use it in fragment shaders.
Why the second code does not work? Am I missing something about multithreaded OpenGL? Should I revert my graphic driver? Or my code is broken?

Thanks in advance!

EDIT: I have two mutexes, one for the main thread (RequestResource method), and another into the detached thread (which iterate through the queue to load resources).

If I use the same mutex for all the two threads, I can use my texture in my compute shader, but my program will not be truly multithreaded anymore.

Why this? This is how I protect my queues:

std::mutex mutexMain, mutexAsync;

Main thread:
mutexMain.lock();
<Add requested resource>
mutexMain.unlock();

Detached thread:
mutexAsync.lock();
<Load resources>
mutexAsync.unlock();

This code above makes my program really work in parallel, but it shows the problem I described above!
Why? How can I achieve good multithreading?
Last edited on
You need a valid context for every thread you wish to call opengl methods in, but normally a context can only be valid in one thread at a time.

Taking care of OpenGL contexts is the issue you seem to be having. Take a look here for some methods on using OpenGL in a multi-threaded environment: https://www.opengl.org/wiki/OpenGL_and_multithreading

The site suggests using multiple contexts, which I agree with.
If you were to use a single GL context, each texture creation (and mipmap creation as well) would cause things to halt for a split second. It would be noticeable to the user.
Ever seen that nasty stuttering when things are loading in games? Let's try to avoid that :D
Thanks for the reply.
I have already read that. I also set up the shared context following this doc, since I'm using GLFW:
http://www.glfw.org/docs/latest/context_guide.html

The problem is this:
I can use the texture in my fragment shader, but not in compute shader. Why? Maybe it's a driver problem? But I don't thing so, otherwise someone should have already noticed this!
How are you trying to access the texture from within your compute shader? Compute shaders have no user-defined inputs, so you have to fetch that data yourself.
https://www.opengl.org/wiki/Compute_Shader
And here's a decent example: http://antongerdelan.net/opengl/compute.html

The issue may lie with the way you are trying to "pass" the texture to your shader.
Anyone doing CPU threading with OpenGL should now switch to Vulkan, which has native support for threading, and also supports real modern GPU computing, (beyond OpenGL compute shaders).
https://www.khronos.org/vulkan/
Last edited on
I resolved! I had to call glFlush right after the resouce was fully loaded. I was calling after iterating through the queue. Now it works!

Anyway, I really want to move to Vulkan, but I'll wait for more tutorials...
Actually, since you mentioned tutorials, here's a good one:
https://vulkan-tutorial.com/Introduction

Does a pretty decent job of explaining what you have to do and why. It's not quite as terse as the documentation, but it's good.
It doesn't cover everything, but it's a good start.

Vulkan is a much more verbose API, and far more powerful, but with that comes some more complexity.
Topic archived. No new replies allowed.