Load textures in background thread, not possible?

Hello,

I read that it is not possible in SDL to load textures in a background thread, while the main thread is rendering the screen, because renderer will not be multi-thread safe, is this still true in latest version?

I guess large open-world game is not possible without this feature…

Br SDLer

If you are using SDL_Renderer, then no, it is not possible. This is because
SDL_Render… functions will only render a texture that was created from
the same renderer.

If you are using OpenGL or DirectX directly, it is possible.
For OpenGL you just need to create another GL context and load textures
with that. This probably won’t work on Android though.
Direct3D9 and above is mostly thread safe, so you should be safe loading
from a separate thread if using DirectX.

However, loading from separate thread, while it looks better in theory, is
in my experience actually slower than loading from the same thread (Just
queue up the textures & load a few every frame), and it doesn’t work easily
on Mobile platforms.

Pallav Nawani
IronCode Gaming Private Limited
Website: http://www.ironcode.com
Twitter: http://twitter.com/Ironcode_Gaming
Facebook: http://www.facebook.com/Ironcode.Gaming
Mobile: 9997478768On Thu, Sep 17, 2015 at 2:07 PM, SDLer wrote:

Hello,

I read that it is not possible in SDL to load textures in a background
thread, while the main thread is rendering the screen, because renderer
will not be multi-thread safe, is this still true in latest version?

I guess large open-world game is not possible without this feature…

Br SDLer


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

well, async io does not mean that you upload textures from a thread. this is not a sdl restriction btw. you should be able to create surfaces from different threads afaik - just not textures because the underlying graphic api does not allow this (or might not allow this)
so the cpu heavy part and io stuff like loading the file and doing the pixel conversions can be made outside the mainthread

martin

http://www.caveproductions.org> Am 17.09.2015 um 10:37 schrieb SDLer :

Hello,

I read that it is not possible in SDL to load textures in a background thread, while the main thread is rendering the screen, because renderer will not be multi-thread safe, is this still true in latest version?

I guess large open-world game is not possible without this feature…

Br SDLer


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I’m able to load images in a background thread just fine… with the
understanding that all renderer interactions must be on the main thread.
Load your image into an SDL_Surface, then pass that to the main thread for
uploading it to a texture.

Jonny DOn Thu, Sep 17, 2015 at 5:04 AM, Pallav Nawani wrote:

If you are using SDL_Renderer, then no, it is not possible. This is
because SDL_Render… functions will only render a texture that was created
from the same renderer.

If you are using OpenGL or DirectX directly, it is possible.
For OpenGL you just need to create another GL context and load textures
with that. This probably won’t work on Android though.
Direct3D9 and above is mostly thread safe, so you should be safe loading
from a separate thread if using DirectX.

However, loading from separate thread, while it looks better in theory, is
in my experience actually slower than loading from the same thread (Just
queue up the textures & load a few every frame), and it doesn’t work easily
on Mobile platforms.

Pallav Nawani
IronCode Gaming Private Limited
Website: http://www.ironcode.com
Twitter: http://twitter.com/Ironcode_Gaming
Facebook: http://www.facebook.com/Ironcode.Gaming
Mobile: 9997478768

On Thu, Sep 17, 2015 at 2:07 PM, SDLer wrote:

Hello,

I read that it is not possible in SDL to load textures in a background
thread, while the main thread is rendering the screen, because renderer
will not be multi-thread safe, is this still true in latest version?

I guess large open-world game is not possible without this feature…

Br SDLer


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Thank you for the advice and quick reply.

Just so I understand this clearly, I guess what you mean to say is that the process of copying the surface to the texture is a very lightweight operation compared to loading the actual file from disk, so if I load everything into the surface in advance the operation to copy it from the surfance into the texture should be so fast it can be done between two render frames? ( that is take like a few milleseconds ? )

That’s something you’ll have to measure for yourself to see if it meets
your needs. It really depends on the amount of image data that you’re
loading and then uploading.

In general, disk access is slower than copying from RAM to the GPU’s
memory. There’s also more work to be done reading in (and often
decompressing) the image format. If you’re uploading a pixel format that
the GPU handles natively, then it’s even better.

Specifically, some numbers I’ve found indicate that normal hard drive
transfer rates are around 125 MB/s and GPU memory bandwidth often reaches
over 100 GB/s. I don’t know for sure that those numbers are directly
comparable, though they seem to indicate a very large disparity.

Jonny DOn Thu, Sep 17, 2015 at 11:53 AM, SDLer wrote:

Thank you for the advice and quick reply.

Just so I understand this clearly, I guess what you mean to say is that
the process of copying the surface to the texture is a very lightweight
operation compared to loading the actual file from disk, so if I load
everything into the surface in advance the operation to copy it from the
surfance into the texture should be so fast it can be done between two
render frames? ( that is take like a few milleseconds ? )


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Are renderers actually bound to specific threads or is it just a matter of
concurrency and protecting shareable data structures from race conditions?

I would guess that you can create a renderer in one thread and use it in
another as long as you lock it so they can’t both stomp on it at the same
time, and you use memory barriers to ensure synchronization.

Is this correct?On Thu, Sep 17, 2015 at 9:10 AM, Jonathan Dearborn wrote:

That’s something you’ll have to measure for yourself to see if it meets
your needs. It really depends on the amount of image data that you’re
loading and then uploading.

In general, disk access is slower than copying from RAM to the GPU’s
memory. There’s also more work to be done reading in (and often
decompressing) the image format. If you’re uploading a pixel format that
the GPU handles natively, then it’s even better.

Specifically, some numbers I’ve found indicate that normal hard drive
transfer rates are around 125 MB/s and GPU memory bandwidth often reaches
over 100 GB/s. I don’t know for sure that those numbers are directly
comparable, though they seem to indicate a very large disparity.

Jonny D

On Thu, Sep 17, 2015 at 11:53 AM, SDLer wrote:

Thank you for the advice and quick reply.

Just so I understand this clearly, I guess what you mean to say is that
the process of copying the surface to the texture is a very lightweight
operation compared to loading the actual file from disk, so if I load
everything into the surface in advance the operation to copy it from the
surfance into the texture should be so fast it can be done between two
render frames? ( that is take like a few milleseconds ? )


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

OpenGL contexts are effectively thread-local. I believe Direct3D is similar.

(It is possible to change the thread an OpenGL context is active in, but then things get more complicated with window event handling and such.)> On Sep 17, 2015, at 6:42 PM, Raymond Jennings wrote:

Are renderers actually bound to specific threads or is it just a matter of concurrency and protecting shareable data structures from race conditions?

I would guess that you can create a renderer in one thread and use it in another as long as you lock it so they can’t both stomp on it at the same time, and you use memory barriers to ensure synchronization.

Is this correct?

Yes. Since loading images to a SDL Surface is entirely done in software,
you can load them in a separate thread & then queue them up for conversion
to textures in the main thread.
You will likely need to sync the two threads somehow (Mutexes etc.) to
prevent both using the queue at the same time.

Pallav Nawani
IronCode Gaming Private Limited
Website: http://www.ironcode.com
Twitter: http://twitter.com/Ironcode_Gaming
Facebook: http://www.facebook.com/Ironcode.Gaming
Mobile: 9997478768On Thu, Sep 17, 2015 at 9:23 PM, SDLer wrote:

Thank you for the advice and quick reply.

Just so I understand this clearly, I guess what you mean to say is that
the process of copying the surface to the texture is a very lightweight
operation compared to loading the actual file from disk, so if I load
everything into the surface in advance the operation to copy it from the
surfance into the texture should be so fast it can be done between two
render frames? ( that is take like a few milleseconds ? )


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Message-ID:
<CAGDaZ_pZnTSnLKrELeUSn35_TF_ANngC3+XQD5UzWB3aPui_XQ at mail.gmail.com>
Content-Type: text/plain; charset=“utf-8”

Are renderers actually bound to specific threads or is it just a matter of
concurrency and protecting shareable data structures from race conditions?

I would guess that you can create a renderer in one thread and use it in
another as long as you lock it so they can’t both stomp on it at the same
time, and you use memory barriers to ensure synchronization.

Is this correct?

I’m not sure about right now, but at least at one time the reason for
only rendering in the main thread was “it’s the Operating System’s
fault!”. I remember, because I used to say it fairly often. The (old)
breakdown is like this:

X Windows theoretically doesn’t care, since it conceptually marshalls
everything over a socket, but see the MS Windows case.

MS Windows used to support multi-threaded access… but everything got
routed through a single render thread anyways, so it didn’t count for
anything other than design purposes. A quick browse suggests that the
current situation is more flexible, but that thread-safe options
reduce performance, as should be expected (synchronization costs).

iOS, used on the iPhone, was spectacular: EVERY time that you tried to
render from ANY thread other than the main one, the main thread and
rendering thread were paused, and the main thread did the rendering
thread’s work. THIS is the specific reason for the “only render in the
main thread” rule: old versions of iOS (I think they might have
changed it) enforced the rule even if you didn’t notice.

So, rendering in a non-main thread? Completely possible! But don’t do
it, because it’s stupid (synchronization reduces performance, despite
the extra threads), and pointless (you can have as many threads as you
want, but rendering is done by hardware that you CANNOT create with a
call to a CreateGPU() function). Just run user I/O and rendering
through your main thread instead: it maximizes performance, while
localizing all user-facing code to a single location, thus following
the Unix Rule: “do one thing, and do it well”. Everything else (e.g.
decompressing image formats, receiving dynamic resources in an MMO
client, modelling the game world) should ideally be what your other
threads get used for.> Date: Thu, 17 Sep 2015 14:42:39 -0700

From: Raymond Jennings
To: SDL Development List
Subject: Re: [SDL] Load textures in background thread, not possible?