Previous Post

SDL GPU: Apple Metal implementation and shader plans

Next Post
SDL GPU: Apple Metal implementation and shader plans
1 / 3
DESCRIPTION

Okay, technically this is cheating, because SDL's GPU API was largely inspired by Metal, making the mapping between the two pretty straightforward, but now the initial work on a Metal backend is in revision control. This still took a lot of effort, but it was useful because it allowed me to check a bunch of assumptions, fix some API mistakes, etc.

That work is sitting here while it incubates, eventually to be merged upstream.

Careful readers might notice this glaring piece of code:

Which of course means that none of this actually works. Not yet. You can't really have a shader-based GPU API without shaders, for crying out loud.

But that is work yet to be done. I'm doing a bunch of research now about various GPU languages. There's a lot to be decided before more code can be written.

The goal is to have both a shader language and a bytecode format that SDL will accept. Many graphics gurus see this project and think "oh cool," then they hear that I might design my own language and bytecode and say "oh no." Which is not them saying "that's a bad idea," so much as "when will the funeral be held for this poor bastard?" I'm continually trying not to think too much about what I've gotten myself into.

There are options, of course. It's not unheard of to grab something off the shelf. There are lots of high-quality languages with open source tools out there, and existing bytecode formats with various levels of documentation.

But what I want--and my desires are unconventional, I get it--is for people to optionally feed shader source code to SDL at runtime. I want you to be able to stuff a shader in a string literal and just be up and running, or dynamically generate shader source to build new effects on the fly, or edit a shader from a Quake-style drop-down console or build your own ShaderToy or whatever. For those that need every ounce of performance, we'll let you cook your shaders offline, but god, handling source directly in SDL is just so compelling to me, that I will walk across glass to make this work before I abandon the idea to bandage my bloodied feet.

This means I can't just point to some existing tool and tell you to compile your shaders with it. I can't even just slurp the source code to some existing tool into SDL, because if we're being honest, compiler developers are not generally interested in keeping things small and simple. It's not like I'm going to just suddenly add an LLVM dependency to the library!

Fortunately, it's not my first time at the rodeo. For MojoShader, I already wrote an HLSL preprocessor, lexer, parser, assembler, and a good portion of the semantic analysis phase, too...all in extremely resource-constrained and embeddable ANSI C. I'm probably going to build on that work here.

If I stay the course, I'm not making promises that you'll get the most optimized compile at runtime. Probably far from it. I want this piece to be fast and small, and if you need to squeeze more performance out of the GPU, you should definitely cook ahead of time with an offline, optimizing compiler. My gamble is lots of people want the utility of source code more than they need the performance boost of precooking, but we'll aim to service both desires.

For those that precook, I want one bytecode format that works everywhere (which means you feed in "SDL bytecode," whatever that might turn out to be, and it spits out DXIL for D3D12, or SPIR-V for Vulkan, etc, but that's our problem, not yours). App developers having to ship separate bytecode for each possible platform is annoying, causes bloat, and fails when new tech shows up later. I haven't decided anything about this yet. Part of me wants to say "you feed us SPIR-V and we figure out what to do with it" so you can use your favorite compiler, but SPIR-V is a verbosely-documented mess. There's 91 extensions to the bytecode format already! Don't get me started on DXIL and MetalLib, which are problems on totally different axes. So this issue is still being considered.

One thing I'm not hesitant about at all, though: the idea of a new language or format. I know I know, we've all gotten this speech before...

...but we live in a world where we already have several incompatible languages and robust tools to move between them, transpiling from one to another, building HLSL to SPIR-V, etc. Adding another to the mix is less about adoption and more about making sure that popular transpilers can target it and moving on. Everyone will still probably write whatever they like to write and that's okay.

So maybe I shouldn't just make another C-alike shader language. Basically all the existing languages are C with some vector extensions and different syntax for accepting inputs and outputs...so maybe the real feature is to not do that. Maybe we go a totally different way. Maybe we all go wild and just write shaders in QBasic!

Anything can happen at this time, so be ready for anything.

(photo credit: Super-cool header image from DuckDuckGo image search for "Apple Metal" led me here.)

Ryan C. Gordon PATREON 3 favs
VIEWS1
FILES3 files
POSTEDMay 18, 2022
ARCHIVEDMay 18, 2022