As far as I understand: the new GPU API is notable because it should allow writing graphics code & shaders once and have it all work cross-platform (including on consoles) with minimal hassle - and previously that required Unity or Unreal, or your own custom solution.
WebGPU/WGSL is a similar "cross-platform graphics stack" effort but as far as I know nobody has written console backends for it. (Meanwhile the SDL3 GPU API currently doesn't seem to support WebGPU as a backend.)
1) SDL_gpu is a pure C library, heavily focused on extreme portability and no depedencies. And somehow it's also an order of magnitude less code than the other options. Or at least this is a difference from bgfx, maybe not so much sokol_gfx.
2) The SDL_gpu approach is a bit lower level. It exposes primitives like command buffers directly to your application (so you can more easily reason about multi-threading), and your software allocates transfer buffers, fills them with data, and kicks off a transfer to GPU memory explicitly rather than this happening behind the scenes. It also spawns no threads - it only takes action in response to function calls. It does take care of hard things such as getting barriers right, and provides the GPU memory allocator, so it is still substantially easier to use than something like Vulkan. But in SDL_gpu it is extremely obvious to see the data movements between CPU and GPU (and memory copies within the CPU), and to observe the asynchronous nature of the GPU work. I suspect the end result of this will be that people write far more efficient renderers on top of SDL_gpu than they would have on other APIs.
[1] https://bkaradzic.github.io/bgfx/overview.html
Edit: Doing more digging according to the end of this forum thread they get compiled to SPIR-V and then to whatever backend is needed, be it GLSL, HLSL, etc.
https://forum.godotengine.org/t/compute-shaders-in-godot/461...
A good example demonstrating where the old SDL 2D API is too limited is with the 2D immediate mode GUI library, Nuklear. It has a few simple API stubs to fill in so it can be adapted to work with any graphics system. But for performance, it wants to batch submit all the vertices (triangle strip). But SDL's old API didn't support anything like that.
The reluctance was the SDL maintainers didn't want to create a monster and couldn't decide where to draw the line, so the line was held at the old 2D API. Then a few years ago, a user successfully changed the maintainers' minds after writing a demonstration showing how much could be achieved by just adding a simple batching API to SDL 2D. So that shifted the mindset and led to this current effort. I have not closely followed the development, but I think it still aims to be a simple API, and you will still be encouraged to pick a full blown 3D API if you go beyond 2D needs. But you no longer should need to go to one of the other APIs to do 2D things in modern ways on modern hardware.
The issue is, if you want complete decoupling (in the sense of orthogonality) among all four of:
- screen (window) size & resolution (especially if game doesn't control)
- sprite/tile image quantization into pixels (scaling, resolution)
- sprite display position, with or without subpixel accuracy
- and physics engine that uses floating point natively (BulletPhysics)
then to achieve this with integer drawing coordinates requires carefully calculating ratios while understanding where you do and do not want to drop the fractional part. Even then you can still run into problem such as, accidentally having a gap (one pixel wide blank column) between every 10th and 11th level tile because your zoom factor has a tenth of a pixel overflow, or jaggy movement with wiggly sprites when the player is moving at a shallow diagonal at the same time as the NPC sprites are at different floating point or subpixel integer coords.
A lot of these problems could be (are) because I think of things from bottom up (even as my list above is ordered) where a physics engine, based on floating point math, is the source of Truth, and everything above each layer is just a viewport abstracting something from the layer beneath. I get the impression SDL was written by and for people with the opposite point of view, that the pixels are important and primary.
And all (most) of these have solutions in terms of pre-scaling, tracking remainders, etc. but I have also written an (unfinished) 3D engine and didn't have to do any of that because 3D graphics is floating point native. After getting the 2D engine 90% done with SDL2 (leaving 90% more to go, as we all know), I had a sort of WTF am I even doing moment looking at the pile of work-arounds for a problem that shouldn't exist.
And I say shouldn't exist because I know the final output is actually using floating point in the hardware and the driver; the SDL1/2 API is just applying this fiction that it's integers. (Neither simple, nor direct.) It gets steam coming out my ears knowing I'm being forced to do something stupid to maintain someone else's fiction, so as nice as SDL otherwise is, I ultimately decided to just bite the bullet and learn to program WebGPU directly.
Maybe SDL_RenderCopy is the wrong API to use to blit things from a sprite sheet onto a display? The docs didn't give any warning if this is the case.
Exposing a modern (in the sense of how self-proclaimed modern APIs like Vulkan, D3D12 and Metal work) GPU API that lets applications written against it to work with various backends (D3D11, D3D12, Vulkan, Metal, whatever Switch and PS5 uses, etc) fits perfectly with what SDL already does for every other aspect of making a game/game engine/framework/etc.
As if it was "needed", it was needed as much as any other of SDL's "subsystems": strictly speaking, not really as you could use some other library (but that could be said for SDL itself) but from the perspective of what the SDL wants to provide (an API to target so you wont have to target each underlying API separately) it was needed for the sake of completeness (previously OpenGL was used for this task if you wanted 3D graphics but that was when OpenGL was practically universally available for the platforms SDL itself officially supported - but nowadays this is not the case).
WebGPU has a couple of design decisions which were necessary to support Vulkan on mobile devices, which make it a very rigid API and even (desktop) Vulkan is moving away from that rigid programming model, while WebGPU won't be able to adapt so quickly because it still needs to support outdated mobile GPUs across all operating systems.
use::sdl2render, gl-rs for raw OpenGL: https://github.com/Rust-SDL2/rust-sdl2?tab=readme-ov-file#op...
But if you want to support Apple's operating systems then you're stuck with OpenGL 4.1 (officially deprecated by Apple 5 years ago) - so no modern GPU features like compute shaders.
You can go the Vulkan route and use MoltenVK for Apple systems, but Vulkan is quite a step up in complexity from OpenGL ("1000 lines of code for a triangle" as people like to say). The goal for SDL3's GPU API is to give you a more approachable (but still plenty flexible) alternative to that.
And similar story for consoles, presumably.
Apparently lots of people asked for "SDL_render but can you add shader support that works for all platforms", so that's the origin story.
SDL3 does also add a higher level audio API - I don't know much about its merits.
> But this is terrible advice in 2021, because OpenGL, for all intents and purposes, is a deprecated API. It still works, it's still got some reasonably modern features, but even if you add up the 22 years Microsoft spent trying to kill it with Apple's seven-or-maybe-twenty, it doesn't change the fact that the brains behind OpenGL would rather you migrate to Vulkan, which is also terrible advice.
> It seems bonkers to tell people "write these three lines of code to make a window, and then 2000 more to clear it," but that's the migration funnel--and meat grinder--that SDL users are eventually going to get shoved into, and that's unacceptable to me.
[0]: https://github.com/libsdl-org/SDL_shader_tools/blob/main/doc... , though the approach that ended up getting merged was an initially-competing approach implemented by FNA folks instead and they seem to have made some different decisions than what was outlined in that markdown doc.
SDL needs to be able to render graphics efficiently, but the SDL2 way is no longer sufficient. Since SDL3 is a major version change, it makes sense to overhaul it while a variety of other API-breaking improvements are being made.
Also, SDL2 has evolved considerably since 2.0.0, and SDL3 continues that evolution while allowing API-breaking changes. SDL3 is not a from-scratch re-write and as an SDL user I dont anticipate migrating from SDL2 to SDL3 will be that difficult.
[edit] And SDL1/2 was never so "thin" that it didn't have its own high-level graphics system, which is useful to have out-of-the-box so that new/basic users can get stuff on screen right away.
[edit2] As ahefner points out, SDL1 was pretty "thin" by modern standards, but it still gave you enough to draw basic stuff on screen without writing your own pixel math, which was pretty helpful back in the 90's.
Very small teams are able to show games running the latest UE5.x engine on native elf/linux, vulkan ("vein", "shmaragon" something).
But the steam client... is still 32bits and x11/GL hard dependent...
I still plan to code my own wayland compositor once the steam client is ELF64 and does proper wayland->x11/vulkan->CPU fallbacks. It will feel weird to have a clean 64bits system.
This abstraction at least has the potential to fulfil the needs of anything more than simple 2D games while allowing you to target the sadly increasingly fragmented graphics API ecosystem (RIP dreams of an universal OpenGL(Next) future). Looks like the hardest part (shader translation) isn't there yet though.
There is a sister project for a cross-platform shading language [1] and another for translating existing ones between each other [2] , but they get done when they get done, and the rest of the API doesn't have to wait for them.
WebGPU was made by a committee of vendors and language-lawyers (standards-lawyers?) with politics and bureaucracy, and it shows. SDL_GPU is made by game developers who value pragmatism above all (and often are looked down upon from the ivory tower because of that).
[1]: https://github.com/libsdl-org/SDL_shader_tools [2]: https://github.com/flibitijibibo/SDL_gpu_shadercross
See also: Not supporting Vulkan or OpenXR at all, using USD instead of glTF for AR content even though it's less well suited for the task, etc. (Well, they probably don't mind that it helps maintain the walled garden either... There's more than one reason for everything)
0: https://docs.google.com/document/d/1F6ns6I3zs-2JL_dT9hOkX_25...
## Khronos
Neil Trevett
## Apple
Dean Jackson Myles C. Maxfield Robin Morisset Maciej Stachowiak Saam Barati
Austin Eng Corentin Wallez Dan Sinclair David Neto James Darpinian Kai Ninomiya Ken Russell Shrek Shao Ryan Harrison
## Intel
Yunchao He
## Mozilla
Dzmitry Malyshau
## W3C
François Daoust Dominique Hazael-Massieux
## Timo de Kort [sic?]
———
I get that Apple/Google have significantly more resources than most organizations on the planet but if these demographics are representative of other (web) standards committees that’s depressing.
Why did it take this long to release the first draft? Compare it to SDL_GPU timeline, start to finish in 6 months. Well, because the yak shaving on WGSL had already begun, and was eating up all the time.
In that sense the WebGPU project is an extremely valuable resource for other wrapper APIs, and saves those other APIs a ton of time.
WebGPU spends a _lot_ of time investigating buggy driver behavior and trying to make things spec-conformant across a lot of disparate and frankly janky platforms. There's a big difference between writing an RHI, and writing a _spec_.
See for yourself: https://github.com/libsdl-org/SDL_shader_tools/blob/main/doc...
Deviations from C-language families, such as "Flow control statements don't need parentheses." are completely unnecessary, I think. Same goes for "Flow control statements must use braces."
One of the developers made an interesting blog post motivating this decision [2] (although some of the finer details have changed since that was written).
There is also a "third party" solution [3] by another one of the developers that enables cross-platform use of SPIR-V or HLSL shaders using SPIRV-Cross and FXC/DXC, respectively (NB: It seems this currently wouldn't compile against SDL3 master).
[1] https://github.com/libsdl-org/SDL/blob/d1a2c57fb99f29c38f509...
I did find an example of using the GPU API, but I didn't see any mention of selecting a backend (Vk, etc.) in the example - is this possible or is the backend selected e.g. based on the OS?
Selected in a reasonable order by default, but can be overridden.
There are three ways to do so:
- Set the SDL_HINT_GPU_DRIVER hint with SDL_SetHint() [1].
- Pass a non-NULL name to SDL_CreateGPUDevice() [2].
- Set the SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING property when calling SDL_CreateGPUDeviceWithProperties() [3].
The name can be one of "D3D11", "D3D12", "Metal" or "Vulkan" (case-insensitive). Setting the driver name for NDA platforms would presumably work as well, but I don't see why you would do that.
The second method is just a convenient, albeit limited, wrapper for the third, so that the user does not have to create and destroy their own properties object.
The global hint takes precedence over the individual properties.
[1] https://wiki.libsdl.org/SDL3/SDL_HINT_GPU_DRIVER
[2] https://wiki.libsdl.org/SDL3/SDL_CreateGPUDevice
[3] https://wiki.libsdl.org/SDL3/SDL_CreateGPUDeviceWithProperti...
The convention itself IS the thing that stops you from fucking that up. It's the kind of thing you do once 2 days into a 30 year career and never again.
I still think it's dumb in Javascript, where you could be using the language on day 2 of learning programming. But in a GPU shader language that it would be almost impossible to understand with no programming experience? It's actually insane.
Having said that everything else about this project looks pretty good, so I guess they can get a pass lol.
The grimfang4/sdl-gpu was one good way to take advantage of modern GPUs in a simple way and workaround the holes/limitations of the old SDL 2D API. The new SDL 3 GPU API will likely make the need for things like grimfang4/sdl-gpu redundant.
I've been going down the Vulkan rabbit hole. It's been fun/enlightening to learn, but the nature of Vulkan makes progress feel slow. I think if SDL3 were available when I started, I would have happily went that route and have more to show for the amount of time I've invested.
I’m also sceptical about their new bytecode for a shading language. Parsing shaders at runtime was not a concern with WebGPU - it’s very fast. Even producing native shaders is fast [1]. It’s the pipeline creation that’s slow, and this bytecode wouldn’t help here.
[1] http://kvark.github.io/naga/shader/2022/02/17/shader-transla...
When I went looking for a cross-platform gaming library, SDL and its API struck the right balance for me. I just wanted a C (++) library I could call to create windows and graphical contexts — a fast sprite rendering framework. I didn't need a whole IDE or a bloated library, didn't want to learn a new language, etc.