GPU: Experimental WebGPU SDLGPU Backend - #16020
Draft
TheeStickmahn wants to merge 91 commits into
Draft
Conversation
Currently only supports Wayland, and it's quite..... bad This is a DRAFT! Just a small proof-of-concept. I'll submit a draft PR to the SDL project to see if I should continue development. If this is greenlit, I might making consider a WGPU SDL_GPU backend if wgpu-native is in a good enough state (maybe Dawn if it isn't?) No promises though! Don't get angry at me if I don't! Current known issues: 1: Error handling is sparse. 2: It only supports the shared library version of wgpu-native, and it does that by just loading it whenever it needs to do something 3: wgpu-native is bad and doesn't implement wgpuGetProcAddress so we're just using SDL_LoadFunction instead. I'd much prefer using the native wgpuGetProcAddress but alas....
Removed webgpu.h and instead we're defining the types ourselves Thank you @HamdyElzanqali for pointing out my stupidity lol
wgpu_native really seems to like statically linking itself (as shown by it not implementing the functionality for dynamic linking), so I added an option to statically link it alongside SDL. How I implemented this almost certainly goes against some convention or guideline in SDL but I'm shooting blind here. I have no idea what to do.
Added Windows support for WGPU, although it is untested since I don't have a Windows machine to test it on.
Added support for Google's Dawn WebGPU implementation. You control which one's used via the option "SDL_WGPU_LIB" where it's either "wgpu-native" or "dawn".
Congratulations; you can now use WebGPU on the Web. I'll make an example eventually, but it's midnight in Sweden and I gotta go to bed.
I'm calling it that simply because it's quicker.
Oh my god, there's SO MUCH STUFF TO DO
Keep on buffering Denji I'm losing my mind
I am so confused here. This backend is effectively a port of the Vulkan backend, but just with WebGPU instead, but that means that I'm often including redundant functionality or attempt to create things that just don't work in WebGPU This backend will have to be polished, as right now it's about as smooth as 1 grit sandpaper.
Since WebGPU shader modules can have multiple types of stages (one shader can have a vertex, fragment, and compute stage in it), I had to make a workaround. I'm actually sorta proud of my solution! How it works is that every "SDL_GPUShader" is actually a "WebGPUShaderReference", which stores the entrypoint, what stage it is, and a hash of the shader source code. That hash is used as the key into a hash table in the renderer, which contains the "actual" shader. I'm bad at explaining things, so I'd just read the code. It's only two functions and I hope I made it easy to read.
YOU WILL GET A 200 LINE FUNCTION AND YOU WILL MERGE IT
Or, I mean; I actually started work on this three days ago. I just hate WebGPU bind groups so much that I've actively procrastinated on implementing them. I will be the first to say this: My implementation of bindings in WebGPU SUCKS. I will not deny that. I made this quickly, and badly, since if this is not done; I will be permanently stuck in a state of procrastination, since I cannot work on multiple things at once. Something something neurodivergence, something something ADHD. Sorry for the lack of commits in the past few days.
Uniforms'll require some extra work since WebGPU expects to receive a buffer while SDL_GPU only provides raw data on the CPU side
I've got it compiling, now I just gotta fix why it crashes.
Why's nothing showing up on the screen 😭
Author
34 out of 34 examples work now! Yipeeeee!
Author
|
With my latest commit implementing SDL_GenerateMipmapsForGPUTexture, I am very happy to say that 34/34 SDLGPU examples are now running on the Web. (Atleast, when I tried it on Linux) |
Collaborator
|
Hooray! :) |
This reverts commit 443b466.
This fixes some issues with Firefox. This is also the final nail in the coffin for wgpu-native support, as it does not implement wgpuInstanceWaitAny.
Next up: Currently the reference count only increases if you use a function with a "cycle" argument. Binding a texture/buffer won't increase the reference count. We'll need some way of counting the references within one command buffer's scope, as right now we're just zeroing the refcount, which would break any command buffers that come next.
|
This is very exciting! I'm so ready to learn the new SDL GPU framework and was wondering about the possibility of deploying to web. Thanks so much for your hard work. 🙏 |
Shit so jank it broke half the damn backend.
They're not implemented very well. Very gross, like most of this project.
Giant commit because my ADHD won and made me work on a thousand things at once Changes: - 33/34 examples now work on Safari! (MacOS 26 Tahoe, M1 Macbook Air) - Only holdout is CompressedTextures, which for some reason is just super broken. I have no idea why, it's not outputting any errors. I'll attempt a frame capture using XCode soon. - Bound resources are now tracked as "used" by in-flight command buffers, preventing release before they're done. - Empty bind groups are no longer bound as "NULL" but instead as their actual bind groups, in order to make Safari stop throwing a fit. - This had the side effect of revealing that the entire bind group system was held together with hopes and dreams. - I then proceeded to re-add new hopes and dreams, fixing it, barely. (see the added FIXME in the SDL_gpu_webgpu.c) - Release of textures, buffers, samplers, fences, & submitted command buffers are now done through a queue system instead of instantly. - Switched fully from callback-based async to future based async to please Emscripten & Asyncify. - Fixed multiple segfaults caused by said switch. - Multiple functions which had use internally but only had SDLGPU opaques as arguments were made into internal versions which use the WebGPU backend's types. - Renamed some functions and variable to reflect their use more accurately. - Command Encoders are now owned by the command buffer and not the renderer. - Bug fixes here and there. Current issues that I care about: (ranked from "this is bad" to "oh shit oh fuck", bottom->top) - The bind group system is hot garbage that'll break any second now. - Destroying the WebGPU device leaks 5MiB of memory. Likely some resource that's not being freed. Also, likely my fault. - GenerateMipmaps is broken on Safari. - Memory leaks in countless initialization / resource creation functions. - This results in anywhere from 6-50KiB of leaked memory per example. - However, there are no continous leaks. Running the backend for 1 second and 1 day will leak the same amount of RAM. (probably, i haven't actually left it running for a day)
ASTC textures need to have their height and width be multiples of the block height & width, so the backend now automagically pads the texture size for you. We should add something to the docs about this (alongside everything else I haven't documented :P)
"What idiot coded this!?" - Idiot who coded this.
Changes: - Automatically pad buffer sizes to be divisible by 4. Didn't know that was a restriction, but I do now. - Pipeline vertex buffer array stride was borked and it hadn't become an issue until now. - Added an "ALIGN_VALUE" macro since it was getting *really* annoying writing the same alignment code over and over again. - The backend now prevents you from creating a sampler with a negative lodMinClamp since WebGPU doesn't like that. These were all targeted fixes for Dear ImGUI's SDLGPU backend, which now works without having to change anything about Dear ImGUI aside from giving it new shaders!
Mapping buffers in WebGPU is insanely slow. Like.... really slow. So, we're not doing that anymore! Now, any "mapped" upload buffer is pretty much an IOU. You're given a piece of malloc'd memory and when you run say UploadToGPUBuffer, it then calls wgpuQueueWriteBuffer for you, making it so that uploading to buffers can be done before the heat death of the universe. The original code is still there though. It's just inaccessible since it'll always choose to pseudo-map because it's much much faster. TLDR: WebGPU can upload the data better than you can. We're gonna let it.
…ove old README's. Changes: - Rewrote my CMake code in order to make it less painful to build this project. On Emscripten it's seamless as it'll automatically link with Emdawnwebgpu. (unless you tell it not to) On native, it'll look for a Dawn library in the CMake source directory, and in /usr/lib if they're on a *nix system. - With the CMake rewrite, I've removed support for wgpu-native, as it doesn't provide any benefits by keeping it in. - I've removed the old README's, since they're old and would likely cause more harm than good. I'll probably make some new ones, but for now it's easy enough to build this backend, and there aren't any HUGE bugs I know of.
…gotten to push it. Sometimes my genius frightens me.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Description
This is my SDLGPU WebGPU backend. I've been working on it for about 1 and a half months, and it's reached a level of "finishedness" where I need feedback on how it works.
As of right now it can run 34 out of the 34 SDLGPU examples, and I've got it running on Windows, Linux, and the Web.
It currently supports most of the SDLGPU standard, however I'm making it a draft PR for a few reasons.
This is the first time I've ever contributed to any project that's not my own (my hubris knows no bounds), so please don't murder me when I do something stupid.
I'll be happy to help with any issues that'll inevitably be found.
(Note that I'm Swedish, so if you're in the Americas I'll be at least ~6 hours behind you.)
(Also, read the README-WEBGPU.md file. Please.)
(TLDR: WebGPU has tortured me and I will further inflict this pain upon others by forcing them to review my code.)
Before this can actually be considered for merging into SDL, we'll need to do a lot of things.
SDL_WEBGPU_USE_PORTSCMake option, by default on)SDL_DownloadFromGPUBuffer... My genius frightens me.//!SDLGPU_COMPAT_F32_UNFILTERABLEsomewhere within your shader code to use non-filterable texture types. This is bad, as not only does it force unfilterable sampling for ALL samplers regardless of type, it is also confusing, as this is also needed for sampling depth textures.Anyways, I'm gonna go play CloverPit now. Have fun!
(Or don't; I'm not your dad.)
Existing Issue(s)
Resolves issue 10768.