-
Notifications
You must be signed in to change notification settings - Fork 3.3k
/
Copy pathwebgpu_jsvalstore.cpp
98 lines (82 loc) · 2.76 KB
/
webgpu_jsvalstore.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright 2020 The Emscripten Authors. All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License. Both these licenses can be
// found in the LICENSE file.
// Make sure this header exists and compiles
// (webgpu_cpp.h includes webgpu.h so that's tested too).
#include <webgpu/webgpu_cpp.h>
#include <emscripten.h>
#include <emscripten/html5_webgpu.h>
class EmJsHandle {
public:
EmJsHandle() : mHandle(0) {}
EmJsHandle(int handle) : mHandle(handle) {}
~EmJsHandle() {
if (mHandle != 0) {
emscripten_webgpu_release_js_handle(mHandle);
}
}
EmJsHandle(const EmJsHandle&) = delete;
EmJsHandle& operator=(const EmJsHandle&) = delete;
EmJsHandle(EmJsHandle&& rhs) : mHandle(rhs.mHandle) { rhs.mHandle = 0; }
EmJsHandle& operator=(EmJsHandle&& rhs) {
int tmp = rhs.mHandle;
rhs.mHandle = this->mHandle;
this->mHandle = tmp;
return *this;
}
int Get() { return mHandle; }
private:
int mHandle;
};
EM_ASYNC_JS(int, init_js_device, (), {
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
return JsValStore.add(device);
});
wgpu::Device init_device() {
EmJsHandle deviceHandle = EmJsHandle(init_js_device());
wgpu::Device device = wgpu::Device::Acquire(emscripten_webgpu_import_device(deviceHandle.Get()));
return device;
}
int main() {
wgpu::Device device = init_device();
wgpu::BufferDescriptor desc = {};
desc.size = 4;
desc.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc;
wgpu::Buffer buffer = device.CreateBuffer(&desc);
EmJsHandle bufferHandle = EmJsHandle(emscripten_webgpu_export_buffer(buffer.Get()));
EM_ASM(
{
const b = JsValStore.get($0);
b.mapAsync(GPUMapMode.WRITE).then(() => {
console.log('Mapping length', b.getMappedRange().byteLength);
b.unmap();
});
}, bufferHandle.Get());
EmJsHandle deviceHandle = EmJsHandle(emscripten_webgpu_export_device(device.Get()));
EmJsHandle textureHandle = EmJsHandle(EM_ASM_INT(
{
const device = JsValStore.get($0);
const t = device.createTexture({
size : [ 16, 16 ],
usage : GPUTextureUsage.COPY_DST,
format : 'rgba8unorm',
});
return JsValStore.add(t);
},
deviceHandle.Get()));
EmJsHandle canvasHandle =
EmJsHandle(EM_ASM_INT({ return JsValStore.add(document.createElement('canvas')); }));
EM_ASM(
{
const device = JsValStore.get($0);
const canvas = JsValStore.get($1);
const texture = JsValStore.get($2);
console.log('Copy', canvas, 'to', texture, 'with', device);
},
deviceHandle.Get(), canvasHandle.Get(), textureHandle.Get());
#ifdef REPORT_RESULT
REPORT_RESULT(0);
#endif
}