File: webgpu_jsvalstore.cpp

package info (click to toggle)
emscripten 3.1.6~dfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 114,112 kB
  • sloc: ansic: 583,052; cpp: 391,943; javascript: 79,361; python: 54,180; sh: 49,997; pascal: 4,658; makefile: 3,426; asm: 2,191; lisp: 1,869; ruby: 488; cs: 142
file content (98 lines) | stat: -rw-r--r-- 2,830 bytes parent folder | download | duplicates (3)
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
}