Skip to content

Commit aac151d

Browse files
committed
Proxy webgpu calls back to the main thread. NFC
Until we have real multi-threaded webgpu support this is probable the best we can do. I tested these locally. I don't think we actually have WebGPU support in our CI yet, but that is something else I'm working on. Fixes: #19645
1 parent 645770f commit aac151d

5 files changed

+33
-11
lines changed

src/library_html5_webgpu.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,8 @@ var LibraryHTML5WebGPU = {
9090
{{{ html5_gpu.makeImportExport('render_bundle_encoder', 'RenderBundleEncoder') }}}
9191
{{{ html5_gpu.makeImportExport('render_bundle', 'RenderBundle') }}}
9292

93+
for (const key of Object.keys(LibraryHTML5WebGPU)) {
94+
LibraryHTML5WebGPU[key + '__proxy'] = 'sync';
95+
}
96+
9397
addToLibrary(LibraryHTML5WebGPU);

src/library_webgpu.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2198,7 +2198,7 @@ var LibraryWebGPU = {
21982198
#endif
21992199

22002200
var bundles = Array.from(HEAP32.subarray(bundlesPtr >> 2, (bundlesPtr >> 2) + count),
2201-
function(id) { return WebGPU.mgrRenderBundle.get(id); });
2201+
(id) => WebGPU.mgrRenderBundle.get(id));
22022202
pass["executeBundles"](bundles);
22032203
},
22042204

@@ -2586,23 +2586,22 @@ var LibraryWebGPU = {
25862586
var device = WebGPU.mgrDevice.get(deviceId);
25872587
var context = WebGPU.mgrSurface.get(surfaceId);
25882588

2589-
25902589
#if ASSERTIONS
25912590
assert({{{ gpu.PresentMode.Fifo }}} ===
25922591
{{{ gpu.makeGetU32('descriptor', C_STRUCTS.WGPUSwapChainDescriptor.presentMode) }}});
25932592
#endif
25942593

25952594
var canvasSize = [
2596-
{{{ gpu.makeGetU32('descriptor', C_STRUCTS.WGPUSwapChainDescriptor.width) }}},
2597-
{{{ gpu.makeGetU32('descriptor', C_STRUCTS.WGPUSwapChainDescriptor.height) }}}
2595+
{{{ gpu.makeGetU32('descriptor', C_STRUCTS.WGPUSwapChainDescriptor.width) }}},
2596+
{{{ gpu.makeGetU32('descriptor', C_STRUCTS.WGPUSwapChainDescriptor.height) }}}
25982597
];
25992598

26002599
if (canvasSize[0] !== 0) {
2601-
context["canvas"]["width"] = canvasSize[0];
2600+
context["canvas"]["width"] = canvasSize[0];
26022601
}
26032602

26042603
if (canvasSize[1] !== 0) {
2605-
context["canvas"]["height"] = canvasSize[1];
2604+
context["canvas"]["height"] = canvasSize[1];
26062605
}
26072606

26082607
var configuration = {
@@ -2646,6 +2645,7 @@ for (var value in LibraryWebGPU.$WebGPU.FeatureName) {
26462645

26472646
for (const key of Object.keys(LibraryWebGPU)) {
26482647
LibraryWebGPU[key + '__i53abi'] = true;
2648+
LibraryWebGPU[key + '__proxy'] = 'sync';
26492649
}
26502650

26512651
autoAddDeps(LibraryWebGPU, '$WebGPU');

test/test_browser.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4664,9 +4664,18 @@ def test_webgl_simple_enable_extensions(self):
46644664
def test_webgpu_basic_rendering(self, args):
46654665
self.btest_exit('webgpu_basic_rendering.cpp', args=['-sUSE_WEBGPU'] + args)
46664666

4667+
@requires_graphics_hardware
4668+
@requires_threads
4669+
def test_webgpu_basic_rendering_pthreads(self):
4670+
self.btest_exit('webgpu_basic_rendering.cpp', args=['-sUSE_WEBGPU', '-pthread', '-sPROXY_TO_PTHREAD'])
4671+
46674672
def test_webgpu_get_device(self):
46684673
self.btest_exit('webgpu_get_device.cpp', args=['-sUSE_WEBGPU', '-sASSERTIONS', '--closure=1'])
46694674

4675+
@requires_threads
4676+
def test_webgpu_get_device_pthreads(self):
4677+
self.btest_exit('webgpu_get_device.cpp', args=['-sUSE_WEBGPU', '-pthread', '-sPROXY_TO_PTHREAD'])
4678+
46704679
# Tests the feature that shell html page can preallocate the typed array and place it
46714680
# to Module.buffer before loading the script page.
46724681
# In this build mode, the -sINITIAL_MEMORY=xxx option will be ignored.

test/webgpu_basic_rendering.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ void GetDevice(void (*callback)(wgpu::Device)) {
2626
}
2727
if (status == WGPURequestAdapterStatus_Unavailable) {
2828
printf("WebGPU unavailable; exiting cleanly\n");
29-
// exit(0) (rather than emscripten_force_exit(0)) ensures there is no dangling keepalive.
29+
// exit(0) (rather than emscripten_force_exit(0)) ensures there is
30+
// no dangling keepalive.
3031
exit(0);
3132
}
3233
assert(status == WGPURequestAdapterStatus_Success);
@@ -410,6 +411,7 @@ int main() {
410411
// emscripten_set_main_loop, and that should keep it alive until
411412
// emscripten_cancel_main_loop.
412413
//
413-
// This code is returned when the runtime exits unless something else sets it, like exit(0).
414+
// This code is returned when the runtime exits unless something else sets
415+
// it, like exit(0).
414416
return 99;
415417
}

test/webgpu_get_device.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
#include <emscripten.h>
1+
#include <stdio.h>
2+
3+
#include <emscripten/em_asm.h>
24
#include <emscripten/html5_webgpu.h>
35

4-
int main() {
6+
__attribute__((constructor)) void init() {
57
EM_ASM({
68
Module['preinitializedWebGPUDevice'] = { this_is: 'a_dummy_object' };
79
});
8-
emscripten_webgpu_get_device();
10+
}
11+
12+
int main() {
13+
WGPUDevice d = emscripten_webgpu_get_device();
14+
printf("emscripten_webgpu_get_device: %p\n", d);
15+
return 0;
916
}

0 commit comments

Comments
 (0)