Multi Thread Error: nvd3dum.pdb could not be found in the selected paths

Hey!,

I use a second std::thread to render some SDL_Textures while loading other SDL_Textures in my main thread. I only use one SDL_Renderer which worked fine before, but since I reinstalled my graphic drivers I always get an exception -> nvd3dum.pdb could not be found in the selected paths. As soon as I remove the second thread || stop loading textures everything works fine. So do I need to use a second SDL_Renderer? But why did it work before? Thanks!

I don’t have the answer to why your application worked before, before the graphic driver update, but I do have some knowledge and insight to multithreading and loading data in another thread.

First of all, SDL is not thread safe, which means that SDL-specific functions (SDL_CreateTexture() for example) should only be executed from the thread that created the window and the renderer, which usually is the main thread.
I’ve had some issues with this in the past and what I end up doing was, in a secondary thread, load an image into an SDL_Surface (with the help of SDL_Image and it’s IMG_Load() function, which is thread safe). Then, in the main thread, before the rendering starts, I call SDL_CreateTextureFromSurface() to create the final SDL_Texture object.
While the loading in the secondary thread occur (let’s say it takes 2 seconds to load all the images), you can render a loading texture in the main thread.

The OP didn’t say what platform he is using. If it’s Windows I know from my own experience that the Direct3D backend is more tolerant of being called from multiple threads than OpenGL. In general, as you say, any SDL texture or render function (any function that ends up making an OpenGL call, anyway) must be called from the thread which created the renderer.

Hey, Thanks for your answers. Sorry if I wasnt more clear(my english isnt perfect :confused:) But I load all textures in my main thread. While the main thread is loading I use a second thread to render some stuff to the window(I dont load any textures in my second thread), using the same renderer. I use Windows.

Looks kinda like this:

class FooThread (…)

void start() {
mIsActive = true;
mThread = std::thread(&FooThread::render, this);
}
void end() {
mIsActive = false;
mThread.join();
}

void FooThread::render()
{
while (mIsActive)
{
SDL_RenderClear(gRenderer); //clear screen
FooThread.render(nullptr);
SDL_RenderPresent(gRenderer); // update screen
}
}

As stated, you may be able to load surfaces in a different thread, but all texture loading and rendering operations must be performed in the thread which created the renderer. You may have got away with it for a while on Windows/Direct3D, but that is not guaranteed and it certainly won’t work when using OpenGL.

Now, I always use a hint to cause SDL to select the OpenGL backend on Windows too; that way I am not taken by surprise by platform differences.

I understand, thank you. So I should just create a new renderer for every thread?