Vulkan is a low-level, highly verbose API designed to extract maximum performance and leverage multiple threads to deal with slower aspects of rendering. Then you chuck that into a single-threaded, slow (relatively) runtime where method calls to the actual implementation are particularly expensive (JavaScript -> native transitions ain't cheap), and that's supposed to be a good idea? Why? Who is supposed to use this for anything useful?
Instead of just porting native features to the web for the sake of porting them make it easier to make use of the hardware's capabilities. Let me throw a GPU shader into a CSS3 transition animation or something like that, for example. That'd be cool and potentially useful instead of a system where you can port some game to the web for the sake of porting it to the web where nobody will ever use it because it sucks compared to the vastly superior native version of the game.
Slow relative to C++, sure. But JS is very fast relative to pretty much any other widely used dynamic language. If we should expose Vulkan bindings to dynamic languages (and why not?) JS is the obvious first choice for a target, given its speed and popularity.
> JavaScript -> native transitions ain't cheap
They're actually very cheap nowadays, because so many benchmarks stress the DOM and C++-implemented builtins. Driver calls, even with Vulkan, far exceed the cost of JS-to-native transitions. glDrawElements() is probably at least 100x slower than a JS-to-native call, the latter of which has latencies measured in nanoseconds.
> Let me throw a GPU shader into a CSS3 transition animation or something like that, for example.
Please, let's not. This will neither be good for designers (modern GPU programming has an enormous learning curve compared to CSS) nor browser developers (shaders would break batching and would expose too many engine-specific internal details).
Exposing it to JS and exposing it to web pages in a browser are two completely different things.
> They're actually very cheap nowadays, because so many benchmarks stress the DOM and C++-implemented builtins. Driver calls, even with Vulkan, far exceed the cost of JS-to-native transitions. glDrawElements() is probably at least 100x slower than a JS-to-native call, the latter of which has latencies measured in nanoseconds.
glDrawElements in vulkan is a couple hundred lines of API calls. I don't think you're fully grokking the orders of magnitude of verbosity that Vulkan brings.
As for the transition cost there's varying levels of cheap, but at the end of the day it's not great. It's raw per-call overhead on an API designed around making an obscene amount of calls, and the overhead is significant. Jumping between these worlds is just not something you want to do very frequently if your goal is performance.
C++-builtins are a completely different class of problems as intrinsics get to play by their own compiler rules than regular JS -> native bindings.
> Please, let's not. This will neither be good for designers (modern GPU programming has an enormous learning curve compared to CSS) nor browser developers (shaders would break batching and would expose too many engine-specific internal details).
So simple pixel shaders are too complex, but vulkan is not?
If a pixel/fragment shader is too much, then so is the entirety of WebGL, and webvulkan would just be pure insanity from that perspective.
Also it doesn't break batching at all, I have no idea what you're talking about there. A pixel shader is just a function with a set of inputs and a color output. It's really quite simple, easily emulated for non-GPU fallbacks, and easily manipulated by the browser.
It would make little sense to expose Vulkan to JS and not to put those bindings in a Web browser.
> glDrawElements in vulkan is a couple hundred lines of API calls. I don't think you're fully grokking the orders of magnitude of verbosity that Vulkan brings.
> As for the transition cost there's varying levels of cheap, but at the end of the day it's not great. It's raw per-call overhead on an API designed around making an obscene amount of calls, and the overhead is significant. Jumping between these worlds is just not something you want to do very frequently if your goal is performance.
It doesn't matter whether it's a couple hundred calls or not. The overhead, which again is measured in nanoseconds, really does not matter. Vulkan's performance demands on API boundary transitions are no worse than that of the DOM, which has been optimized for decades.
> C++-builtins are a completely different class of problems as intrinsics get to play by their own compiler rules than regular JS -> native bindings.
No, they don't. They are one and the same in many JS engines. (I can't speak for all engines, but I'm familiar with SpiderMonkey, where a JSNative is a JSNative, whether a builtin or a DOM method.) SpiderMonkey nowadays even knows about things like purity of various DOM methods and will optimize accordingly. (bz used this to make Dromaeo really fast.)
> So simple pixel shaders are too complex, but vulkan is not?
Fragment shaders are too complex for CSS. They aren't too complex for programmatic manipulation in JS. The reason is simple: CSS is a high-level declarative language intended to be accessible to designers, while JS is an imperative language mainly used by programmers.
> Also it doesn't break batching at all, I have no idea what you're talking about there.
As you know, switching shader programs can only be done in between draw calls.
> A pixel shader is just a function with a set of inputs and a color output.
With hundreds of pages of specification describing how all the different operations that that function can perform must behave.
I agree that functionality like fragment shaders is useful, as long as it's declarative and fits in with the rest of CSS. In fact, we already have it: the CSS filter property.
Nevertheless, even if some implementations actually do call driver, the GP's point is that the whole point of Vulkan is getting rid of global state to allow parallel command buffer creation. JS is single threaded so, no matter how cheap or expensive the calls are, you won't be able to take advantage of Vulkan since you are running just one thread.
Nobody forbids you from calling it "driver", of course but then the whole point of "going into the driver" does not make sense, since there is no syscall and it's just a regular function.
What I've linked to is a driver. Everybody calls it that.
When you go download a driver for graphics cards, whether on Linux or Windows, that driver actually consists of multiple components, some of them running in kernel-mode and some of them running in user-mode. It's basically the exo-kernel principle, but without feeling the need of giving it a fancy name :)
There's a broader history of user-mode drivers not just for graphics, and not just in the obvious case of micro-kernels. User-mode USB drivers used to be a thing, for example (and I guess they still are for some more obscure hardware).
If you don't believe me or crzwdjk, just go ahead and actually profile a system running an OpenGL application. The syscall overhead -- as in, the overhead of transitioning between user and kernel mode -- is laughably negligible compared to everything else. Also, the vast majority of driver CPU time is spent in user space building up command submissions. The final command submission itself isn't free of course, but clearly more time is spent processing precisely those glDraw*() calls that you seem to think don't matter.
That's great. Why do you think you are the only one? And what should I believe exactly here? That there is a syscall in every OpenGL API? If you are writing drivers you know it's not true yourself. The syscall overhead is not laughable, it's tens of thousands of clocks.
>Also, the vast majority of driver CPU time is spent in user space building up command submissions.
Exactly. OpenGL system (if you want to call it "driver" be my guest, DirectX does not do that for example, neither do other APIs) works mostly in the user space.
> The final command submission itself isn't free of course, but clearly more time is spent processing precisely those glDraw*() calls that you seem to think don't matter.
??? I don't even know what are you arguing here. Let's rewind. Someone said that "driver calls" are expensive. And it's true for people who understand drivers as a part of OS, not "user mode drivers", which are just shared libs. I corrected, saying that there is no actual driver call in the sense that people understand, i.e. there is no OS call or "syscall" since the OpenGL "driver" is mostly a shared library in the user space. You seem to agree with me. Now, I am well aware that some calls are expensive. I even know why. Some are not though. On some the overhead of moving data from a managed language to the GPU will be much greater than the call itself. E.g. setting an index buffer.
It still does not make it true that there are syscalls in the OpenGl calls anyways.
A driver does not mean a kernel module. It's often that, but it does not exclusively mean that. Userspace drivers are still drivers.
The library that gets loaded into the process is part of the driver. It's provided by the GPU vendor and it's specific to the hardware you're running. It maps API calls to hardware-specific commands. Aka, it's a driver. It just happens to be implemented as a userspace library for most of the work.
edit: "The API has to execute efficiently on WebAssembly and in multi-threaded environment. That means no GC allocations during the rendering loop in order to avoid the garbage collection pauses."
Instead we ended up with a stack machine & sbrk.
The JVM doesn't even have unsigned integers!
C++ or Rust -> wasm bytecode is great. Soon we'll be writing directly to command buffers, no fuss.
But ~nobody wants to build UIs like that anyway, so what's your target audience?
As for 3D applications what 3D applications? Do you really think Maya is going to be ported to a browser? Why would they bother? Why would they restrict themselves like that?
The web has no advantages in this space, and the needs of those markets is already being served with superior technology and infrastructure.
Please have a nice weekend.
I assure you those casual game companies are not going to want to go anywhere near vulkan or similar, though, and they are generally fine with the performance scripting languages already give them (hence why they were in flash instead of java applets)
They want strong 2D graphics capabilities primarily, which is largely an ignored category. <canvas> has a 2D context, but it's pretty crappy.
To give one example, bananabread is a tech demo showing off what can be done with asm.js and WebGL (performance is likely to get even better with WASM):
http://kripken.github.io/misc-js-benchmarks/banana/index.htm...
As for whether a VM has an overhead compared to native, of course it does, but you're not going to convince anyone of your viewpoint by stating something that's already obvious to us all. The performance of web-based games doesn't have to be the best, it just has to 'good enough'. I personally don't think we'll fast adoption of WebVR, but I'm glad it exists as it helps to have it as a goal to improve 3D performance, almost certainly leading to reducing the performance overhead of browsers (as low latency is a key component of a good VR experience).