The rise of wgpu
gfx-rs.github.io
gfx-rs.github.io
C99 Hello Triangle:
https://github.com/gfx-rs/wgpu/blob/master/examples/hello_tr...
Rust Hello Triangle:
https://github.com/gfx-rs/wgpu/blob/master/examples/hello_tr...
Both look very neat and tidy IMHO.
The C99 version could also use nested designated initialization right in the function call, this would make it look very similar to the Rust version, e.g.:
WGPUBlendStateId blend_state_0 = wgpu_device_create_blend_state(
device,
&(WGPUBlendDescriptor) {
.blend_enabled = false,
.write_mask = WGPUColorWriteFlags_ALL,
.color = {
.src_factor = WGPUBlendFactor_One,
.dst_factor = WGPUBlendFactor_Zero,
.operation = WGPUBlendOperation_Add,
},
.alpha = {
.src_factor = WGPUBlendFactor_One,
.dst_factor = WGPUBlendFactor_Zero,
.operation = WGPUBlendOperation_Add,
}
});
But of course that's a matter of taste :)- The types help, seeing "WGPUSwapChainId" tells me exactly what sort of object is returned (a reference to some object held elsewhere), we don't get this in Rust because of type inference.
- Rust doesn't help in this example because it's just a bunch of API calls... so it's a more complex language for nothing. Obviously this doesn't generalize.
- The event handling is much simpler in the C code, this also doesn't generalize.
Check out RLS (the rust language server) to get intellisense like this working in your favorite editor.
I think the solution is for diff viewers incl. those on the web to support something like intellisense, but obviously we are a very long way away from that.
I tend to find, personally, that this kind of thing doesn't interfere strongly with reviewing. I think this is because I have an extensive background in dynamically typed languages and ones with strong inference like Rust, so I'm more used to it, whereas people who don't come from said backgrounds prefer more explicitness. YMMV of course!
-Z unstable-options -Zunpretty=hir,typed
// source
pub fn square(num: i32) -> i32 {
num * num
}
// expanded
use ::std::prelude::v1::*;
extern crate std;
pub fn square(num: i32)
-> i32 ({ ((num as i32) * (num as i32) as i32) } as i32)
You can try on https://rust.godbolt.org/Might be worth mentioning that (AFAIK) type inference is entirely optional in Rust. If you prefer to write explicit types on your decls that's fine. (I suspect there are pathological cases where the type is impractical to write, but you'd have been screwed then anyway.)
This won't help you when reading other people's code, obviously.
Rust has more syntactic elements than the C, in this code that’s clear, but cleanliness can mean different things.
Rust has a module system, so no global namespace issues, but does require all of the :: separators.
Rust has cleaner ways of dealing with cross platform compile time switches, thus we don’t see the CPP macros for different platform targets.
To me, those are cleaner, but I’m familiar with Rust and C, which is why I asked.
entrypoint: ”main”
as the argument for a shader program seems like it could be turned into a default.Convention over configuration isn’t always the answer, but some times at least it can help reduce clutter.
In the future the api will perhaps have builders as an option.
&BlaDesc {
bla: 1,
blub: 2,
..Default::default()
}With the builder pattern, you can do so: require them in the builder constructor.
I couldn't disagree more.
Compared to D3D11 or Metal? Arguable.
Compared to GL? For a simple triangle also arguable, but GL gets messier much quicker for complex cases.
I don’t know anything about this, but node wrappers for webrender: https://github.com/cztomsik/node-webrender
And even a demo app: https://github.com/cztomsik/slack-app/blob/master/README.md
For instance here is an example of such a render function, it's just 50 lines of C, implemented on top of slim cross-platform headers with support for Windows, Linux, macOS, iOS, Android and WASM:
https://github.com/floooh/sokol-samples/blob/0576ed914290a35...
(this is from this demo which is 513 KBytes all in all: https://floooh.github.io/sokol-html5/wasm/imgui-highdpi-sapp...)
With such a bloat-free UI system you can create statically linked single-exes with embedded font data and shaders in a few hundred KBytes, and people are starting to use this for "proper" desktop tools too (not just as embedded tool UIs for games etc)
Plus, you will have to deal with the fact that while you can push large amounts of computation out quickly to the GPU, reading back the results to CPU involves long latencies and scheduling issues. It often results in a loss of the kind of generality people take for granted in pure CPU programming, from little things like not being able to printf() in the middle of a program, to larger things like having to manually hook up every function call in GPU land by submitting a detailed description of your specific desired calling convention in triplicate (i.e. uniforms, varyings and attributes).
The alternative model is platform specific front-ends backed by a mostly universal back-end library. Used successfully by Transmission, VLC, and others. All the conveniences of being tailored to each platform in terms of UX and integration, but with the same basic broad functionality. But few companies will want to pay for 2x the devs, while in the open source world in practice the various platforms diverge so much they almost feel like different apps entirely. Still, it is much preferable over a 300MB+ hog that can't display more than 2 screenfuls of chat.
I sure hope so! It's no secret that I've been hoping that someone will put together all the pieces we've been developing—WebRender, Pathfinder, gfx-rs, font-kit, skribo, etc.—and create a lightweight UI framework for Rust. None of us have the time to do so, but all the pieces are there…
stemming from https://raphlinus.github.io/rust/2018/12/16/rust-2019.html?
It’s probably been a decade now that all software that can be written by normals has already been written.
Projects like this thrive because as opposed to fulfilling some user’s need, they are very intellectually stimulating to work with and thus make programming fun again.
A program that isn’t joyful to write never gets written.
Have the big three confirmed intent to support WebGPU?
Also, what is the state of WebGL backend support for gfx-rs? I'm watching [0] eagerly. That would be a great practical step towards gfx-rs in browsers today.
Google, Apple, Microsoft, Mozilla, and Intel are the core of the working group.
> Also, what is the state of WebGL backend support for gfx-rs?
Since you are watching the actual work on the PR, I don't think there is more to tell :)
Mozilla is implementing it in Gecko, Google is implementing it in Blink, and Apple is implementing it in WebKit.
Now, implementing it doesn't guarantee they'll eventually ship it, but it would be surprising if they didn't.
So currently the plan is to finish the spirv_cross changes, expand the unified OpenGL/WebGL bindings (the crate I've been calling "glow"), and rebase the gfx PR with these changes. Then I think we should be able ready to merge the initial WebGL support, and we can keep iterating on it (like we've done with the other backends).
This part makes me nervous. Isn't it basically saying "we wrote perfectly safe C and made a Rust wrapper for it"?
Shameless plug: We have a graph based approach which automates all intermediate resource allocations and scheduling. I am hoping we can opensource it or something similar as it separates definitions of the algorithms nicely from how they are scheduled in the end (async compute on amd and so forth are all automatic). We also have backend implementations for all the major modern apis.
If they do not have explicit barriers within a device then it has to do state tracking, bringing the CPU overhead back into the level of OpenGL and making multithreaded command recording almost useless. The original WebGPU (now WebMetal) proposal did have explicit barriers.
WebGPU also has the usual way of allocating memory. You create buffers and images, as an example look https://github.com/gpuweb/gpuweb/blob/master/design/BufferOp...
We also have explicit resource creation available as when you create a texture you just want a texture. No fancy stuff there.
-I thought the original article was just gfx-rs supporting the WebGPU as a backend.- EDIT: I did misunderstand it. It's wgpu-rs that's a new api. The WebGPU in between had me confused.
EDIT2: I misunderstood it doubly. It is WebGPU implementation on top of gfx-rs. So points about WebGPU stand.
> If they do not have explicit barriers within a device then it has to do state tracking, bringing the CPU overhead back into the level of OpenGL and making multithreaded command recording almost useless.
I don't believe this to be correct. We have the state tracking implemented in wgpu-rs, and it's designed from day one to support multi-threaded command recording. Implementation-wise, every command buffer knows which resources it expects in which states, and what states they end up with. When it's submitted, the WebGPU queue inserts necessary transitions into those input states, and it tracks the current state of all resources.
Yes, there is some CPU overhead there for sure, but it's not yet clear how significant it is. Keep in mind that WebGPU has to validate the states, which is roughly the same complexity as deriving those states in the first place, hence our decision to do so.
> WebGPU also has the usual way of allocating memory.
Not directly. Currently, users can create resources and not care about their lifetimes. This is contrary to Vulkan/D3D12 memory allocation with transient resources, which is what your frame graphy library helps with.
[1] https://github.com/gpuweb/gpuweb/blob/c1afbe9e88a06aa61f82a1...
It's good to know that the state tracker is bit more refined than what is required for something like OpenGL.
>Yes, there is some CPU overhead there for sure, but it's not yet clear how significant it is. Keep in mind that WebGPU has to validate the states, which is roughly the same complexity as deriving those states in the first place, hence our decision to do so.
One of the benefits of prebuilding the frame as a graph ahead of time is that one can do vast majority of the validation ahead of time, thus making the heavy operation be explicit for the user. Also the validation happens only once, instead of every frame.
Just like when you bind pipeline you do not have to again validate that all of the shaders etc are valid. Just that it's valid for this renderpass etc. In OpenGL one has to validate the graphics pipeline state after every change to it, whereas in WebGPU it's enough to validate most of it on creation. Similar thing applies to building the state transitions ahead of time.
> Currently, users can create resources and not care about their lifetimes.
For some reason I assumed that if there is a createTexture there ought to be destroyTexture for it. But indeed there is not. I have a few questions pertaining to this.
How does it know I'm not going to need a texture anymore? If it has to keep the data valid for eternity it will at the very least have to store it to ram or disk because it never knows if I'm going to submit a command that references it again.
This sounds to me that some applications where lots of assets are streamed in will explode in memory usage. Or then the user has to do manual pooling, which can be even more difficult and bug prone.
Since the API is about accessing the GPU not only for rendering, but also for compute tasks, I think WebGPU is an ok name.
Throwing in some random word creations: * Processing#, * UnifiedProcessing#, * ParallelProcessing#, * Accel#,
Prefixes *: Web/Open/Lib/Imperial/Federal/Continuum
#Suffixes: Library/Hole/Sink/Chain/[not Unit (it's for Hardware)]
And yes, Apple is clearly on board :)
But at the end of the day it became clear that Vulkan is simply not fit for many things, including the Web. It can't be the new lingua franca simply because it's too complex for users to pick up.
And OpenGL was a mess too to be honest, at least after 30 years of development. Vulkan started right off with an even bigger API complexity.
It might actually be a good idea to have a handful of low-level, small-ish GPU-vendor and/or platform-specific 3D-APIs, each of those is most likely less complex and has less design-compromises than Vulkan.
https://webkit.org/blog/8482/web-high-level-shading-language...
That's not correct as far as I'm aware. All of us (Mozilla, Google, Apple) had prototypes in the works for the new API, and WebGPU just happened to be the name of the Apple one, which we borrowed later.
As for the binding models, it's a hot topic. I believe the discussions are converging towards Vulkan-like binding model at the end of the day.
Today, WebGPU takes some bits from Metal and Vulkan, it is not fair to say that it's "based on Apple Metal API".
Does this mean that gfx-rs (the low level API) is deprecated and no longer maintained?