4 ms·
The helmet gif is breathtaking. The eliding over abstractions as an API simplification is a bit disingenuous. gl.Foo(...) gl.Bar(...) gl.Baz(...) into
by berdon 7y ago
The helmet gif is breathtaking. The eliding over abstractions as an API simplification is a bit disingenuous.
gl.Foo(...)
gl.Bar(...)
gl.Baz(...)
into
encoder.setPipeline(pipeline)
Unless they're intuiting what needs to be done, those Far, Boo, and Baz calls are still happening somewhere.
That's not to say abstraction isn't a useful way of separating out code. And OpenGL/WebGL's pipeline setup has always been a bit archaic. This is definitely progress - it's just not really being presented directly in the article.
- flohofwoe 7y ago...it's the exact same difference like GL to modern 3D-APIs (like Metal, Vulkan or D3D12, or even D3D11). The cost for those Foo, Bar and Baz calls is paid once during the creation of the pipeline object which usually happens at the start of the application. Making that pipeline object active during rendering is very cheap (about as cheap as one of those gl.Foo() calls).
- berdon 7y agoMy point was the post is misleadingly saying: "These 15 lines go away and are replaced by this 1 line". That's not what's happening (unless I'm mistaken) and the code examples are comparing apples to oranges.
- flohofwoe 7y agoWell, yeah ok, the lines move from the drawFrame() function into the init() function basically. It may not be less code to type, but it's much less code to run :)
- berdon 7y agoI re-read the article - and that's just not what the article implies. They make the implication that there's a reduction in "code to type". I suppose this is just an exercise in pedantry though. I'm excited, regardless, for any API simplification.
- jacobolus 7y agoThis seems pretty clear and unambiguous to me > Most 3D applications render more than a single object. In WebGL, each of those objects requires a collection of state-changing calls before that object could be rendered. [...] All the pieces of state in the WebGL example are wrapped up into a single object in WebGPU, named a “pipeline state object.” Though validating state is expensive, with WebGPU it is done once when the pipeline is created, outside of the core rendering loop. As a result, we can avoid performing expensive state analysis inside the draw call. Also, setting an entire pipeline state is a single function call, reducing the amount of “chatting” between Javascript and WebKit’s C++ browser engine. > Resources have a similar story. Most rendering algorithms require a set of resources in order to draw a particular material. In WebGL, each resource would be bound one-by-one. However, in WebGPU, resources are batched up into “bind groups”. [... In both APIs] multiple objects are gathered up together and baked into a hardware-dependent format, which is when the browser performs validation. Being able to separate object validation from object use means the application author has more control over when expensive operations occur in the lifecycle of their application. The clear point in both of these comparisons is that the same operations must be done in both APIs, but the WebGPU version allows much of the work to be pre-computed, allowing the draw calls (where the performance bottleneck lies) to have as little overhead as possible.
- berdon 7y agoThat's neither clear nor unambiguous. The text I highlighted including their summary of it states there is a reduction of code. Not only that, the "both APIs" part you're mentioning isn't even pertaining to the code but rather the execution of the pipeline. My point is, and has been, that they should focus on the perf gains and reduce the misleading sentiment that it has simplified the API footprint.
- deleted 7y ago[deleted]
- berdon 7y agoAnd clear and unambiguous to me: gl.UseProgram(program1); gl.frontFace(gl.CW); gl.cullFace(gl.FRONT); gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_MIN); gl.blendFuncSeparate(gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA, gl.ZERO); gl.colorMask(true, false, true, true); gl.depthMask(true); gl.stencilMask(1); gl.depthFunc(gl.GREATER); gl.drawArrays(gl.TRIANGLES, 0, count); >>> On the other hand, rendering a single object in WebGPU might look like: encoder.setPipeline(renderPipeline); encoder.draw(count, 1, 0, 0);
- Rusky 7y agoMisleading if the point were that the API got smaller or easier, maybe. But the point is instead that the amount of work done in the main render loop is smaller. Those 15 lines do go away in that sense- they only happen once on startup under the new API.
- kevingadd 7y agoFor years if not decades, imperative OpenGL calls like the ones above have been internally building state objects and command buffers. APIs like Vulkan and WebGPU just expose the state objects and command buffers directly. Part of the issue with OpenGL is that the state is hidden behind the driver (due to how much things have changed since the APIs were specified) and you build the state with a massive number of API calls that often need to get RPC'd into a sandbox or what have you. A carefully specified API like WebGPU that exposes state objects can allow those to be built outside the sandbox (in user content) and efficiently RPCd in a smaller set of calls. It is realistic to say those calls go away, even if similar calls have to happen "once". In comparison, when I port native apps over to WebGL I'm invoking dozens of WebGL API calls every time I draw some tris and it's SUPER SLOW. Compared to that the cost of doing some basic setup is a rounding error.