microsoft / DirectXTK

The DirectX Tool Kit (aka DirectXTK) is a collection of helper classes for writing DirectX 11.x code in C++

Home Page:https://walbourn.github.io/directxtk/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature request] Optionally leave the final mipmap generation call to the user when loading a texture with autogen mipmaps

twaritwaikar opened this issue · comments

Thank you for working on this awesome library.

Currently, in our engine, we are loading a set of textures concurrently. We have a thread pool that handles loading each texture on a separate thread. Since we are using WIC and the DDS loader for texture loading, the problem with loading textures concurrently is that we cannot use the auto-mipmap generation, since calls to the D3D11 context are not threadsafe.

To our surprise, calls to D3D11 device were running properly when made concurrently so we decided to turn off mipmap generation and just not do mipmaps in our engine at all.

We would really like a feature where we could send an additional flag named deferMipmapGeneration or similar inside the auto-mipmaps texture loading functions in WICTextureLoader and DDSTextureLoader which will essentially do everything that the auto mipmap generation overload does but it leaves out actually calling the device context's GenerateMips() function and expects the user to call it later.

This way we would be able to load all mipmap-able textures concurrently and when all our concurrent texture loading is finished, we could one-by-one call GenerateMips() on each of those textures.

The best solution in general is to pre-generate mips offline, store them in DDS files, and then load them fully mip'd. I'm assuming you already considered that and have some reason why you need to use auto-gen mips instead. With the non-auto-gen mip scenario, you can use initData and do it in one call to the device.

I get where you are going here, and it would be fairly easy to have the call to GenerateMips guarded by another load option flag. The problem is that is not the only use of the thread-unsafe context. I also have to use it to copy the top-level mip data because you can only use initData if it has the same number of mips as the target.

As long as you require auto-gen mips, it's going to have an inherently serial behavior. If delaying the GenerateMips call is useful, I'm happy to add that flag, but it doesn't make the loader thread-safe in this scenario as it still needs the context.

@walbourn If adding the flag still wouldn't make it threadsafe then I guess this request isn't really affordable (it is technically but the use-case requires complete threadsafe behavior and not adding the flag alone). Creating mips offline and then loading them at runtime might just be the best way since we basically don't have to change any code to load mipmaps like that and we already are using the DDS texture loader.

Closing :)