I have the following ‘loadEngine’ method in my Babylon.js project. The idea is to create a WebGPU engine on browsers compatible with WebGPU. Otherwise, create the standard WebGL 2.0 Babylon.js engine if the client is using a browser not compatible with WebGPU. Either way, a Babylon.js engine is created.
private loadEngine(): Promise<Engine | WebGPUEngine> {
const returnEngine = new Promise<Engine | WebGPUEngine>(
(resolve, reject) => {
try {
// If client is using a browser compatible with WebGPU
if (navigator.gpu) {
const engine = new WebGPUEngine(this.canvas);
engine.initAsync().then(() => {
resolve(engine);
});
} else {
resolve(new Engine(this.canvas, true));
}
} catch (exception) {
reject(exception);
}
},
);
return returnEngine;
}
I noticed today that this exception is being thrown when I open my Babylon.js application using Google Chrome. The exception is not thrown when I open my application with Firefox , but that is because Firefox is not yet compatible with WebGPU, so the standard engine is initialised there: no issue.
The exception clearly states that the problem occured during the “WebGPU creation/initialisation”. There is an uncaught exception below this that also states ‘requestDevice’ failed to execute on ‘GPUAdapter’. I thought this was odd as I am not calling this method anywhere in my code.
My best guess is that Babylon.js has not updated in response to recent browser updates. The WebGPUEngine was working fine in Google Chrome before, and I noticed that Chrome did announce that it was going to remove ‘requestAdapterInfo()’ from GPUAdapter in future updates. Therefore, I assumed that Babylon.js is calling this ‘requestDevice’ method somewhere, yet the Chrome browser no longer supports this method. Hence, it used to work, but no longer does.
Is anyone else able to initialise a WebGPUEngine in their Babylon.js project. Am I missing something here?
So, it seems to be a problem specific to your code. We would need a reproduction somewhere to be able to help more (as the code you dumped above looks good).
Also, I’ve been told that creating a large number of devices can cause this error, so make sure you don’t have a bug that creates the engine a large number of times in the page.
Ok. So I found out what the issue was, and you were right: the problem seem to be down to the fact that I was calling ‘scene.render()’ within a ‘setInterval()’ callback function, which was executing 120 times per second.
This was the approach I took rather than calling the standard ‘runRenderLoop()’ method from the Babylon.js engine as my application is reading from an XML file. Each XML tag has a ‘time’ attribute, and my application needs to respond to these tags at the time value of these attributes. Thus, I reasoned that using the ‘setInterval()’ approach meant that I could speed up or slow down the application time to my specific liking. ‘runRenderLoop()’, after all, does not allow you to vary the number of times it is invoked. It is always invoked at 60 times a second no matter what.
In summary, in my code where I am calling the rendering loop, I replaced this…
const customFPS = 60; //120 or 250
// run the main render loop
this.renderLoop = setInterval(() => {
scene.render();
}, 1000 / customFPS);
… with the following.
engine.runRenderLoop(() => {
scene.render();
});
The downside, of course, is that I can no longer change the number of times ‘scene.render()’ is being called per each second, which was the entire reason why I was using the ‘setInterval()’ approach to begin with rather than calling ‘runRenderLoop()’.
Oh well… I guess I will simply have to accept that this is a limitation of WebGPU, at least for now. At least I got to the bottom of the issue. I will now mark this discussion as resolved.