thatcosmonaut / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
1 stars 2 forks source link

Add IsTextureFormatSupported and GetBestSampleCount functions #2

Closed TheSpydog closed 2 months ago

TheSpydog commented 2 months ago

This PR adds two new functions to the SDL_GPU API, for querying texture format capabilities.

One of them is very simple -- it just gets the "best" supported multisample count that is <= a desired sample count. Just like in FNA3D.

The other function is more complicated. Not all formats are supported on all hardware, and even hardware that does support a format does not necessarily support it in all contexts. A particular format may be compatible with the COLOR_TARGET usage but only if the texture is 2D, not a cubemap. Another format may support all usages except compute. There are, sadly, many such cases. It gets complicated fast.

The IsTextureFormatSupported function aims to solve that problem. You can simply ask SDL_GPU, "Hey, is it ok to use format X with texture type Y for usage Z?" And you'll get an SDL_bool with the answer. The main use case I have in mind for this is depth-stencil format queries. The client can check if (e.g.) D24_S8 is supported, and if not, manually fall back to D32_S8. But you could also do this for other "risky" texture formats that may not be supported on all the target hardware. Maybe a certain machine doesn't support COMPUTE usage with a certain texture type, in which case you can perform your calculations CPU-side instead.

However, requiring manual fallback logic is a burden to put on the client, so for (relatively) trivial cases like depth-stencil, we could handle it automatically in each of the SDL_GPU backends.

However... I think we can do one better: SDL_gpu.c itself could perform the fallback logic. Before calling into the driver's CreateTexture function, we can sneak a quick peek at the supported usages/types for the TextureCreateInfo. If we're trying to create a texture with an unsupported depth format, we can swap it out in the create info there. By the time the backend gets the texture create info, all the data will be valid. (We could also sneak in some other validation here if we wanted.)

I have not implemented the above, because it does add some overhead for each texture create call and I wanted to run this idea past you all first. (Although realistically the overhead will probably be inconsequential compared to the cost of actually, you know, creating a texture.)

We may also want to add a similar function for checking buffer support, since buffers also have usage flags.