blob: b37f02d1c22ea866867050cfc9b190042544b85e [file] [log] [blame]
// 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
}