9 ms·
The rise of wgpu
- flohofwoe 8y agoWorth 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_triangle_c/main.c https://github.com/gfx-rs/wgpu/blob/master/examples/hello_tr... Rust Hello Triangle: https://github.com/gfx-rs/wgpu/blob/master/examples/hello_triangle_rust/main.rs 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 :)
- mrec 8y agoI was about to say "yeah, you should look at flohofwoe's Sokol stuff for an example of nested init", then saw the username :)
- skocznymroczny 8y agoFor me, the C version looks actually cleaner than the Rust one.
- kvark 8y agoI'm genuinely interested in why you find it cleaner, please elaborate?
- gpm 8y agoThree thoughts: - 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.
- asddgsgsaxg 8y ago> seeing "WGPUSwapChainId" tells me exactly what sort of object is returned (a reference to some object held elsewhere) Check out RLS (the rust language server) to get intellisense like this working in your favorite editor.
- jonathanyc 8y agoI think that in reviewing code this is definitely something where languages with type inference lose clarity; Rust is even worse because of the Deref/Into idioms. 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.
- devit 8y agoYou could have the compiler produce a fully explicit version (I'm not sure if Rust can do that out of the box at the moment)
- steveklabnik 8y ago~~It can't.~~ See below, it can! 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!
- bluejekyll 8y agoIs 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 8y agoI 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 8y agoI'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 8y agoOne 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.
- singularity2001 8y ago>> very neat and tidy I couldn't disagree more.
- flohofwoe 8y agoIt's definitely cleaner and less code compared to a Vulkan "hello triangle". Compared to D3D11 or Metal? Arguable. Compared to GL? For a simple triangle also arguable, but GL gets messier much quicker for complex cases.
- xtf 8y agoWebGPU. 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.
- flohofwoe 8y agoThe API has nothing in common with WebGL (or generally OpenGL) though, and the "inspired-by" name WebMetal would be even more confusing ;) Since the API is about accessing the GPU not only for rendering, but also for compute tasks, I think WebGPU is an ok name.
- kvark 8y agoGpu = 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 8y agoAMD 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)]
- majortennis 8y agoagreed unless its a web based graphics card, terrible name
- deleted 8y ago[deleted]
- ttflee 8y agoI 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 8y agoIt'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".
- kodablah 8y ago> 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
- kvark 8y ago> Have the big three confirmed intent to support WebGPU? 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 :)
- gsnedders 8y ago> 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.
- grovesNL 8y agoAs mentioned in the PR, I have a version of spirv_cross (the Rust wrapper of SPIRV-Cross) working with the wasm32-unknown-unknown target now (https://github.com/grovesNL/spirv_cross/pull/92 https://github.com/grovesNL/spirv_cross/pull/92). 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).
- mikepurvis 8y agoHow 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.
- kvark 8y agoThere is an imgui port to wgpu-rs in progress - https://github.com/unconed/imgui-wgpu-rs https://github.com/unconed/imgui-wgpu-rs . I don't know how feasible it would be to compile it to WASM later on, we'll see.
- alex_duf 8y agoWhat you want is pretty much HTML isn't it?
- bluejekyll 8y agoWebrender might be the abstraction you want. I don’t know anything about this, but node wrappers for webrender: https://github.com/cztomsik/node-webrender https://github.com/cztomsik/node-webrender And even a demo app: https://github.com/cztomsik/slack-app/blob/master/README.md https://github.com/cztomsik/slack-app/blob/master/README.md
- flohofwoe 8y agoThere's no need to tie the 2D UI framework to the underlying rendering API. If you look at immediate-mode UI systems like Dear ImGui, those provide vertices, indices and a command list for rendering in each frame, and it's very easy to render those commands through all existing 3D APIs. 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/0576ed914290a352e2f4c56c6b1577a77977f4cf/sapp/imgui-highdpi-sapp.cc#L270-L319 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.html 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)
- _-___________-_ 8y ago"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 8y agoThere 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/
- gardaani 8y ago> 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 8y agoThis 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
- dman 8y agoThe 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).
- kvark 8y agoUltimately, it doesn't matter at this point. If the API is usable and popular, hardware vendors may later decide to pave the way from it directly to the driver. For now, layering on top of the existing native graphics APIs is fine. And yes, Apple is clearly on board :)
- dman 8y agoI dont care about what API wins, but the current stalemate is very disappointing. For all its flaws OpenGL was lingua franca for the longest time, now that Apple has deprecated it, I hope it gets replaced by a single credible alternative. The current fragmentation where every platform is pushing its own graphics API is wasteful when it comes to developer productivity.
- asddgsgsaxg 8y agoAnd that's why we are excited about gfx-rs in this thread.
- dman 8y agoI would be more excited if there was evidence that graphics card vendors and platform vendors were onboard. Ie some commitment that webgpu is the replacement for Vulkan / Metal / DirectX / OpenGL (with backers of each of these APIs communicating an intent to deprecate it in favor of webgpu). In this case it would be a very exciting move because the amount of entropy in the world would reduce greatly. On the other hand if webgpu is an abstract API with Vulkan/Metal/DirectX/OpenGL backends then the net entropy in the world is actually increasing and now there is one new additional thing for people to debug / port to.
- Jasper_ 8y agoIf this is WebGPU, where's the WHLSL and questionably bad faith arguments for days on incompatible binding models from Apple?
- kvark 8y agoThe 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.
- sharpneli 8y agoEven 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 8y agoI 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 8y agoThe 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/BufferOperations.md 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.
- kvark 8y agoI 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/c1afbe9e88a06aa61f82a12e890359075952bd40/design/sketch.webidl https://github.com/gpuweb/gpuweb/blob/c1afbe9e88a06aa61f82a1...