
The rise of wgpu - jobstijl
https://gfx-rs.github.io/2019/03/06/wgpu.html
======
flohofwoe
Worth looking at the hello-triangle examples for the C- and Rust-APIs:

C99 Hello Triangle:

[https://github.com/gfx-
rs/wgpu/blob/master/examples/hello_tr...](https://github.com/gfx-
rs/wgpu/blob/master/examples/hello_triangle_c/main.c)

Rust Hello Triangle:

[https://github.com/gfx-
rs/wgpu/blob/master/examples/hello_tr...](https://github.com/gfx-
rs/wgpu/blob/master/examples/hello_triangle_rust/main.rs)

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 :)

~~~
skocznymroczny
For me, the C version looks actually cleaner than the Rust one.

~~~
bluejekyll
Is this because you’re not as familiar with Rust as you are with C?

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.

~~~
alkonaut
I think the Rust style that uses ”constructorless” struct initialization
really makes the code too verbose in this case. It’s nice and explicit in a
way but having to say e.g

    
    
        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.

~~~
flohofwoe
I'm not sure if the builder pattern is better than designated
initialization... AFAIK in Rust you can get something similar (fill up missing
members with their default values) with ..Default::default(), like:

    
    
        &BlaDesc {
            bla: 1,
            blub: 2,
            ..Default::default()
        }

~~~
masklinn
One annoyance of this is that you can't require fields to be explicitly
provided anymore.

With the builder pattern, you can do so: require them in the builder
constructor.

------
mikepurvis
How practical would it be to produce a 2D UI using a framework built on these
kinds of APIs? I'm wondering if there's a future down the road for multi-
platform desktop apps with the convenience of Electron-like development and
distribution, but where the native clients are able to be much thinner than a
whole browser.

~~~
pcwalton
> I'm wondering if there's a future down the road for multi-platform desktop
> apps with the convenience of Electron-like development and distribution, but
> where the native clients are able to be much thinner than a whole browser.

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…

~~~
steveklabnik
I'm excited for Druid, personally.

~~~
markdog12
I'm guessing that's [https://github.com/xi-
editor/druid](https://github.com/xi-editor/druid)

stemming from
[https://raphlinus.github.io/rust/2018/12/16/rust-2019.html](https://raphlinus.github.io/rust/2018/12/16/rust-2019.html)?

~~~
steveklabnik
Yes, sorry!

------
kodablah
> The code runs on a variety of platforms [...] eventually the Web (when the
> browsers gain support for the API, which is also in our scope of work).

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.

0 - [https://github.com/gfx-rs/gfx/pull/2554](https://github.com/gfx-
rs/gfx/pull/2554)

~~~
gsnedders
> Have the big three confirmed intent to support WebGPU?

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.

------
_-___________-_
"We don’t even rely on Rust syntax and features for safety, since it’s handled
at the lower level [...]"

This part makes me nervous. Isn't it basically saying "we wrote perfectly safe
C and made a Rust wrapper for it"?

~~~
kvark
There isn't such thing as "safe C" :) Any pointer passed in can be garbage
with unintended consequences. Surely, there are _some_ bits of Rust that are
required for the safe operation over wgpu-native, such as taking an address of
a borrowed struct. What this quote is trying to convey is that we don't rely
on super strong types for safety, for example, like Vulkano [1] does. We can
expose Rust API that borrows command buffers and resources where they are used
and does the move semantics, and at the same time we can expose Rust API that
implements Copy for all the objects, and it's still going to be fine, because
the C layer doesn't rely on a lot of constraints from above.

[1] [http://vulkano.rs/](http://vulkano.rs/)

------
sharpneli
Even webgpu makes performance portability hard and keeps the user manually
setting barriers etc. We could use a modern but yet higher level api.

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.

~~~
kvark
I believe the plug is misplaced here, since you misunderstood the article
contents. WebGPU does _not_ have the user manually setting barriers or
allocating memory.

~~~
sharpneli
The current version of the webgpu doesn't talk much about synchronization
primitives
[https://github.com/gpuweb/gpuweb](https://github.com/gpuweb/gpuweb) (same
that can be reached from the original post), the little it reveals is DX12
style running fences that are used in multi-adapter system.

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...](https://github.com/gpuweb/gpuweb/blob/master/design/BufferOperations.md)

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.

~~~
kvark
I do agree that the information on what WebGPU does and what not isn't clearly
available. It's all in the IDL ([1]), where you may notice no API for explicit
barriers. We are working on more readable documentation/specification.

> 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...](https://github.com/gpuweb/gpuweb/blob/c1afbe9e88a06aa61f82a12e890359075952bd40/design/sketch.webidl)

~~~
sharpneli
Thanks for pointing out the IDL. That tells a lot more about the API.

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.

~~~
Jasper_
The assumption is to rely on GC and if a resource is not reachable in JS (or
in existing bindings), then it can't be submitted again, so it can safely be
cleaned up. There is also an explicit GPUTexture.destroy() method if you want
to free up the GPU memory immediately.

------
xtf
WebGPU. That's an awful name. Given WebGL is taken and already in version 2.
But WebGPU sounds like a virtual GPU for GameStreaming. Even GLWeb would be
nicer.

~~~
kvark
Gpu = graphics + compute, it's more than just "GL" (graphics library). The
fact that WebGL reached version 2 is hardly relevant, since it's a different
API, likely to be overshadowed in some 5 years.

~~~
xtf
AMD calls their CPU with integrated Graphics APU (Accelerated Processing
Units), why not thinking that forth, oh OpenAL (Audio Library) is already in
use, WebAL would confuse more. We are running out of acronyms.

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)]

------
dman
The important question is - are the graphics and platform vendors onboard?
Does webgpu sit directly on top of graphics drivers or is this just a
MoltenVK/Angle style abstraction layer that abstracts away OpenGL / Vulkan /
Metal? Has someone done the hard work of getting Apple onboard for using this
outside the browser (ie as a Metal replacement).

~~~
yig
Apple (arguably) initiated the WebGPU API development effort. Surprisingly,
Apple is pushing for a shader language based on Microsoft's HLSL. Some of the
others are pushing for a lower-level, non-human-readable shader binary format
instead (which is what Vulkan takes in).

[https://webkit.org/blog/8482/web-high-level-shading-
language...](https://webkit.org/blog/8482/web-high-level-shading-language/)

~~~
kvark
> Apple (arguably) initiated the WebGPU API development effort.

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.

------
Jasper_
If this is WebGPU, where's the WHLSL and questionably bad faith arguments for
days on incompatible binding models from Apple?

~~~
kvark
The group hasn't yet agreed on what shading language is directly digested by
the WebGPU implementation. We may provide some helpers in the future to
convert WHLSL to SPIRV for wgpu-rs to consume, just like today we provide GLSL
to SPIRV helpers, and our examples use GLSL in Vulkan style.

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.

------
ttflee
I would double down on WebGPU given it was based upon Apple Metal API. BTW,
canvas was a web clone of Core Graphics, more or less.

~~~
kvark
It's not based on Metal API. There is quite a bit of confusion in here, let me
clarify. Originally, Apple called their (WebGL Next?) prototype WebGPU, and it
looked like Metal. Then the W3C group was formed with all the browser vendors,
and they agreed to give that name to the group's work. That doesn't relate to
the actual prototype code, which was implemented in Safari preview and is
about to be removed from there.

Today, WebGPU takes some bits from Metal and Vulkan, it is not fair to say
that it's "based on Apple Metal API".

------
gardaani
_> With wgpu-rs we can finally deprecate the old gfx and have a solid
recommendation for people getting started with graphics in Rust._

Does this mean that gfx-rs (the low level API) is deprecated and no longer
maintained?

~~~
kvark
This deprecates the _old_ gfx (also called "pre-ll" for pre-low-level), which
you can find at [1]. The new gfx (also called "gfx-hal" for hardware
abstraction layer) is not deprecated, clearly, since wgpu-rs runs on it :)

[1] [https://crates.io/crates/gfx](https://crates.io/crates/gfx)

