react-native-webgpu 0.14.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cpp/rnwgpu/api/DestroyedError.h +26 -0
- package/cpp/rnwgpu/api/GPUDevice.cpp +17 -9
- package/cpp/rnwgpu/api/GPUSharedFence.cpp +39 -12
- package/cpp/rnwgpu/api/GPUSharedFence.h +21 -4
- package/cpp/rnwgpu/api/GPUSharedTextureMemory.cpp +80 -4
- package/cpp/rnwgpu/api/GPUSharedTextureMemory.h +29 -6
- package/lib/typescript/src/types.d.ts +2 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/types.ts +14 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <string>
|
|
4
|
+
|
|
5
|
+
#include "webgpu/webgpu_cpp.h"
|
|
6
|
+
|
|
7
|
+
namespace rnwgpu {
|
|
8
|
+
|
|
9
|
+
// 'GPUSharedFence "label"', or just the class name when unlabeled.
|
|
10
|
+
inline std::string describeDestroyed(const char *className,
|
|
11
|
+
const std::string &label) {
|
|
12
|
+
return label.empty() ? std::string(className)
|
|
13
|
+
: std::string(className) + " \"" + label + "\"";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Reports a use of a destroyed object the way Dawn reports an invalid one: a
|
|
17
|
+
// validation error, caught by error scopes or else delivered to the device's
|
|
18
|
+
// uncapturederror event.
|
|
19
|
+
inline void reportDestroyedUse(wgpu::Device &device, const char *className,
|
|
20
|
+
const std::string &label, const char *method) {
|
|
21
|
+
auto message = "Destroyed " + describeDestroyed(className, label) +
|
|
22
|
+
" used in " + method + "().";
|
|
23
|
+
device.InjectError(wgpu::ErrorType::Validation, message.c_str());
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
} // namespace rnwgpu
|
|
@@ -345,14 +345,21 @@ std::shared_ptr<GPUSharedTextureMemory> GPUDevice::importSharedTextureMemory(
|
|
|
345
345
|
#endif
|
|
346
346
|
|
|
347
347
|
auto memory = _instance.ImportSharedTextureMemory(&desc);
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
348
|
+
// Dawn reports a failed import (feature missing, unusable handle) as a
|
|
349
|
+
// validation error and returns an error object rather than null, with no
|
|
350
|
+
// format in its properties: the format getter of any texture created from
|
|
351
|
+
// it would throw. Fail the import instead.
|
|
352
|
+
wgpu::SharedTextureMemoryProperties properties{};
|
|
353
|
+
if (memory == nullptr ||
|
|
354
|
+
memory.GetProperties(&properties) != wgpu::Status::Success ||
|
|
355
|
+
properties.format == wgpu::TextureFormat::Undefined) {
|
|
356
|
+
throw std::runtime_error(
|
|
357
|
+
"GPUDevice::importSharedTextureMemory(): the import failed - is the "
|
|
358
|
+
"'shared-texture-memory-iosurface' (Apple) or "
|
|
359
|
+
"'shared-texture-memory-ahardware-buffer' (Android) feature enabled "
|
|
360
|
+
"on the device, and the handle a usable IOSurface / AHardwareBuffer?");
|
|
361
|
+
}
|
|
362
|
+
return std::make_shared<GPUSharedTextureMemory>(_instance, std::move(memory),
|
|
356
363
|
std::move(label));
|
|
357
364
|
}
|
|
358
365
|
|
|
@@ -402,7 +409,8 @@ std::shared_ptr<GPUSharedFence> GPUDevice::importSharedFence(
|
|
|
402
409
|
"GPUDevice::importSharedFence(): ImportSharedFence returned null - is "
|
|
403
410
|
"the matching 'shared-fence-*' feature enabled on the device?");
|
|
404
411
|
}
|
|
405
|
-
return std::make_shared<GPUSharedFence>(std::move(fence),
|
|
412
|
+
return std::make_shared<GPUSharedFence>(_instance, std::move(fence),
|
|
413
|
+
std::move(label));
|
|
406
414
|
}
|
|
407
415
|
|
|
408
416
|
async::AsyncTaskHandle GPUDevice::createComputePipelineAsync(
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
#include <cstdint>
|
|
4
4
|
#include <string>
|
|
5
5
|
|
|
6
|
+
#include "DestroyedError.h"
|
|
7
|
+
|
|
6
8
|
#if defined(__ANDROID__)
|
|
7
9
|
#include <fcntl.h>
|
|
8
10
|
#endif
|
|
@@ -32,10 +34,30 @@ std::string sharedFenceTypeToString(wgpu::SharedFenceType type) {
|
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
// Dawn reports a fence it can't export (an invalid one) as a validation error
|
|
38
|
+
// and leaves the type at 0. Fail the call too, like a destroyed fence does,
|
|
39
|
+
// rather than returning a record with no type and no handle.
|
|
40
|
+
void throwIfNotExported(jsi::Runtime &runtime,
|
|
41
|
+
const wgpu::SharedFenceExportInfo &info) {
|
|
42
|
+
if (info.type == wgpu::SharedFenceType(0)) {
|
|
43
|
+
throw jsi::JSError(runtime, "GPUSharedFence::export() failed");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
35
47
|
} // namespace
|
|
36
48
|
|
|
49
|
+
void GPUSharedFence::injectDestroyedError(const char *method) {
|
|
50
|
+
reportDestroyedUse(_device, CLASS_NAME, _label, method);
|
|
51
|
+
}
|
|
52
|
+
|
|
37
53
|
jsi::Value GPUSharedFence::exportInfo(jsi::Runtime &runtime, const jsi::Value &,
|
|
38
54
|
const jsi::Value *, size_t) {
|
|
55
|
+
// Fails like an export Dawn rejects: a validation error, then the throw.
|
|
56
|
+
if (!_instance) {
|
|
57
|
+
injectDestroyedError("export");
|
|
58
|
+
throw jsi::JSError(runtime,
|
|
59
|
+
"GPUSharedFence::export(): the fence was destroyed");
|
|
60
|
+
}
|
|
39
61
|
wgpu::SharedFenceExportInfo info{};
|
|
40
62
|
uint64_t handle = 0;
|
|
41
63
|
|
|
@@ -44,25 +66,30 @@ jsi::Value GPUSharedFence::exportInfo(jsi::Runtime &runtime, const jsi::Value &,
|
|
|
44
66
|
wgpu::SharedFenceMTLSharedEventExportInfo mtlInfo{};
|
|
45
67
|
info.nextInChain = &mtlInfo;
|
|
46
68
|
_instance.ExportInfo(&info);
|
|
69
|
+
throwIfNotExported(runtime, info);
|
|
47
70
|
handle = reinterpret_cast<uint64_t>(mtlInfo.sharedEvent);
|
|
48
71
|
#elif defined(__ANDROID__)
|
|
49
|
-
// Android: the handle is an OS file descriptor (sync_fd). Dawn's ExportInfo
|
|
50
|
-
// owned by the SharedFence and closed when the
|
|
51
|
-
//
|
|
52
|
-
//
|
|
72
|
+
// Android: the handle is an OS file descriptor (sync_fd). Dawn's ExportInfo
|
|
73
|
+
// returns a BORROWED fd — it is owned by the SharedFence and closed when the
|
|
74
|
+
// fence is destroyed. This exported handle is documented as caller-owned (the
|
|
75
|
+
// caller must close() it), so dup() it. Without the dup the same fd is closed
|
|
76
|
+
// twice — once by the caller and once by Dawn on fence destruction — tripping
|
|
77
|
+
// Android's fdsan (double-close abort).
|
|
53
78
|
wgpu::SharedFenceSyncFDExportInfo fdInfo{};
|
|
54
79
|
info.nextInChain = &fdInfo;
|
|
55
80
|
_instance.ExportInfo(&info);
|
|
56
|
-
|
|
57
|
-
|
|
81
|
+
throwIfNotExported(runtime, info);
|
|
82
|
+
int exportedFd = fdInfo.handle >= 0
|
|
83
|
+
? ::fcntl(fdInfo.handle, F_DUPFD_CLOEXEC, 0)
|
|
84
|
+
: fdInfo.handle;
|
|
58
85
|
handle = static_cast<uint64_t>(static_cast<uint32_t>(exportedFd));
|
|
59
86
|
#else
|
|
60
|
-
// react-native-webgpu only targets Apple (Metal) and Android (Vulkan). On any
|
|
61
|
-
// other platform there is no native handle convention to expose, so fail
|
|
62
|
-
// rather than handing back a meaningless handle of 0.
|
|
63
|
-
throw jsi::JSError(runtime,
|
|
64
|
-
|
|
65
|
-
|
|
87
|
+
// react-native-webgpu only targets Apple (Metal) and Android (Vulkan). On any
|
|
88
|
+
// other platform there is no native handle convention to expose, so fail
|
|
89
|
+
// loudly rather than handing back a meaningless handle of 0.
|
|
90
|
+
throw jsi::JSError(runtime,
|
|
91
|
+
"GPUSharedFence::export(): unsupported platform (only "
|
|
92
|
+
"Apple/Metal and Android/Vulkan are supported)");
|
|
66
93
|
#endif
|
|
67
94
|
|
|
68
95
|
jsi::Object result(runtime);
|
|
@@ -17,9 +17,10 @@ class GPUSharedFence : public NativeObject<GPUSharedFence> {
|
|
|
17
17
|
public:
|
|
18
18
|
static constexpr const char *CLASS_NAME = "GPUSharedFence";
|
|
19
19
|
|
|
20
|
-
explicit GPUSharedFence(wgpu::
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
explicit GPUSharedFence(wgpu::Device device, wgpu::SharedFence instance,
|
|
21
|
+
std::string label)
|
|
22
|
+
: NativeObject(CLASS_NAME), _device(std::move(device)),
|
|
23
|
+
_instance(std::move(instance)), _label(std::move(label)) {}
|
|
23
24
|
|
|
24
25
|
public:
|
|
25
26
|
std::string getBrand() { return CLASS_NAME; }
|
|
@@ -33,19 +34,35 @@ public:
|
|
|
33
34
|
std::string getLabel() { return _label; }
|
|
34
35
|
void setLabel(const std::string &label) {
|
|
35
36
|
_label = label;
|
|
36
|
-
_instance
|
|
37
|
+
if (_instance) {
|
|
38
|
+
_instance.SetLabel(_label.c_str());
|
|
39
|
+
}
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
// Releases the fence now (closing its sync fd on Android) rather than when
|
|
43
|
+
// the JS object is garbage collected, which a runtime making fences every
|
|
44
|
+
// frame may not do for a while. Dawn keeps its own reference as long as it
|
|
45
|
+
// needs the fence (a beginAccess wait). A later use is a validation error
|
|
46
|
+
// and a throw.
|
|
47
|
+
void destroy() { _instance = nullptr; }
|
|
48
|
+
|
|
39
49
|
static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
|
|
40
50
|
installGetter(runtime, prototype, "__brand", &GPUSharedFence::getBrand);
|
|
41
51
|
installMethod(runtime, prototype, "export", &GPUSharedFence::exportInfo);
|
|
52
|
+
installMethod(runtime, prototype, "destroy", &GPUSharedFence::destroy);
|
|
42
53
|
installGetterSetter(runtime, prototype, "label", &GPUSharedFence::getLabel,
|
|
43
54
|
&GPUSharedFence::setLabel);
|
|
44
55
|
}
|
|
45
56
|
|
|
46
57
|
inline wgpu::SharedFence get() { return _instance; }
|
|
47
58
|
|
|
59
|
+
// Reports a use of the destroyed fence the way Dawn reports an invalid
|
|
60
|
+
// object: a validation error, caught by error scopes or else delivered to
|
|
61
|
+
// the device's uncapturederror event.
|
|
62
|
+
void injectDestroyedError(const char *method);
|
|
63
|
+
|
|
48
64
|
private:
|
|
65
|
+
wgpu::Device _device;
|
|
49
66
|
wgpu::SharedFence _instance;
|
|
50
67
|
std::string _label;
|
|
51
68
|
};
|
|
@@ -1,15 +1,62 @@
|
|
|
1
1
|
#include "GPUSharedTextureMemory.h"
|
|
2
2
|
|
|
3
|
+
#include <algorithm>
|
|
3
4
|
#include <memory>
|
|
4
5
|
#include <stdexcept>
|
|
5
6
|
#include <string>
|
|
6
7
|
|
|
7
8
|
#include "Convertors.h"
|
|
9
|
+
#include "DestroyedError.h"
|
|
8
10
|
|
|
9
11
|
namespace rnwgpu {
|
|
10
12
|
|
|
13
|
+
void GPUSharedTextureMemory::destroy() {
|
|
14
|
+
if (!_instance) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
(void)_instance.GetProperties(&_properties);
|
|
18
|
+
if (!_accessed.empty()) {
|
|
19
|
+
// Dawn's contract is an endAccess() for every beginAccess(), but Dawn
|
|
20
|
+
// doesn't check it when the memory goes away. Report the misuse; the
|
|
21
|
+
// access itself is left as is (ending it would hand its fences to no one).
|
|
22
|
+
auto message = "Destroyed " + describeDestroyed(CLASS_NAME, _label) +
|
|
23
|
+
" with an access still open: call endAccess() first.";
|
|
24
|
+
_device.InjectError(wgpu::ErrorType::Validation, message.c_str());
|
|
25
|
+
_accessed.clear();
|
|
26
|
+
}
|
|
27
|
+
_instance = nullptr;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void GPUSharedTextureMemory::injectDestroyedError(const char *method) {
|
|
31
|
+
reportDestroyedUse(_device, CLASS_NAME, _label, method);
|
|
32
|
+
}
|
|
33
|
+
|
|
11
34
|
std::shared_ptr<GPUTexture> GPUSharedTextureMemory::createTexture(
|
|
12
35
|
std::optional<std::shared_ptr<GPUTextureDescriptor>> descriptor) {
|
|
36
|
+
if (!_instance) {
|
|
37
|
+
// Like a texture Dawn can't create from the memory: the validation error
|
|
38
|
+
// says why, and the texture is an error texture. As Dawn does, it is
|
|
39
|
+
// described by the caller's descriptor, or else by the memory's
|
|
40
|
+
// properties. It owns no GPU memory, so it reports no memory pressure.
|
|
41
|
+
injectDestroyedError("createTexture");
|
|
42
|
+
wgpu::TextureDescriptor desc{};
|
|
43
|
+
std::string label;
|
|
44
|
+
if (descriptor.has_value() && descriptor.value() != nullptr) {
|
|
45
|
+
Convertor conv;
|
|
46
|
+
if (!conv(desc, descriptor.value())) {
|
|
47
|
+
throw std::runtime_error(
|
|
48
|
+
"GPUSharedTextureMemory::createTexture(): Error with "
|
|
49
|
+
"GPUTextureDescriptor");
|
|
50
|
+
}
|
|
51
|
+
label = descriptor.value()->label.value_or("");
|
|
52
|
+
} else {
|
|
53
|
+
desc.usage = _properties.usage;
|
|
54
|
+
desc.size = _properties.size;
|
|
55
|
+
desc.format = _properties.format;
|
|
56
|
+
}
|
|
57
|
+
return std::make_shared<GPUTexture>(_device.CreateErrorTexture(&desc),
|
|
58
|
+
std::move(label), false);
|
|
59
|
+
}
|
|
13
60
|
if (!descriptor.has_value() || descriptor.value() == nullptr) {
|
|
14
61
|
auto texture = _instance.CreateTexture();
|
|
15
62
|
return std::make_shared<GPUTexture>(texture, "");
|
|
@@ -34,6 +81,12 @@ void GPUSharedTextureMemory::beginAccess(
|
|
|
34
81
|
throw std::runtime_error(
|
|
35
82
|
"GPUSharedTextureMemory::beginAccess(): texture is null");
|
|
36
83
|
}
|
|
84
|
+
// Fails like an access Dawn rejects: a validation error, then the throw.
|
|
85
|
+
if (!_instance) {
|
|
86
|
+
injectDestroyedError("beginAccess");
|
|
87
|
+
throw std::runtime_error(
|
|
88
|
+
"GPUSharedTextureMemory::beginAccess(): the memory was destroyed");
|
|
89
|
+
}
|
|
37
90
|
wgpu::SharedTextureMemoryBeginAccessDescriptor desc{};
|
|
38
91
|
desc.initialized = initialized;
|
|
39
92
|
desc.concurrentRead = false;
|
|
@@ -45,7 +98,13 @@ void GPUSharedTextureMemory::beginAccess(
|
|
|
45
98
|
if (fences.has_value()) {
|
|
46
99
|
for (const auto &state : *fences) {
|
|
47
100
|
if (state && state->fence) {
|
|
48
|
-
|
|
101
|
+
auto fence = state->fence->get();
|
|
102
|
+
if (!fence) {
|
|
103
|
+
state->fence->injectDestroyedError("beginAccess");
|
|
104
|
+
throw std::runtime_error(
|
|
105
|
+
"GPUSharedTextureMemory::beginAccess(): a fence was destroyed");
|
|
106
|
+
}
|
|
107
|
+
rawFences.push_back(std::move(fence));
|
|
49
108
|
values.push_back(state->signaledValue);
|
|
50
109
|
}
|
|
51
110
|
}
|
|
@@ -53,10 +112,12 @@ void GPUSharedTextureMemory::beginAccess(
|
|
|
53
112
|
if (!rawFences.empty()) {
|
|
54
113
|
desc.fenceCount = rawFences.size();
|
|
55
114
|
desc.fences = rawFences.data();
|
|
115
|
+
desc.signaledValueCount = values.size();
|
|
56
116
|
desc.signaledValues = values.data();
|
|
57
117
|
} else {
|
|
58
118
|
desc.fenceCount = 0;
|
|
59
119
|
desc.fences = nullptr;
|
|
120
|
+
desc.signaledValueCount = 0;
|
|
60
121
|
desc.signaledValues = nullptr;
|
|
61
122
|
}
|
|
62
123
|
|
|
@@ -78,6 +139,7 @@ void GPUSharedTextureMemory::beginAccess(
|
|
|
78
139
|
if (status != wgpu::Status::Success) {
|
|
79
140
|
throw std::runtime_error("GPUSharedTextureMemory::beginAccess() failed");
|
|
80
141
|
}
|
|
142
|
+
_accessed.push_back(texture->get());
|
|
81
143
|
}
|
|
82
144
|
|
|
83
145
|
jsi::Value GPUSharedTextureMemory::endAccess(jsi::Runtime &runtime,
|
|
@@ -88,6 +150,12 @@ jsi::Value GPUSharedTextureMemory::endAccess(jsi::Runtime &runtime,
|
|
|
88
150
|
throw jsi::JSError(
|
|
89
151
|
runtime, "GPUSharedTextureMemory::endAccess(): expected (texture)");
|
|
90
152
|
}
|
|
153
|
+
if (!_instance) {
|
|
154
|
+
injectDestroyedError("endAccess");
|
|
155
|
+
throw jsi::JSError(
|
|
156
|
+
runtime,
|
|
157
|
+
"GPUSharedTextureMemory::endAccess(): the memory was destroyed");
|
|
158
|
+
}
|
|
91
159
|
auto texture = GPUTexture::fromValue(runtime, args[0]);
|
|
92
160
|
|
|
93
161
|
wgpu::SharedTextureMemoryEndAccessState state{};
|
|
@@ -104,18 +172,26 @@ jsi::Value GPUSharedTextureMemory::endAccess(jsi::Runtime &runtime,
|
|
|
104
172
|
if (status != wgpu::Status::Success) {
|
|
105
173
|
throw jsi::JSError(runtime, "GPUSharedTextureMemory::endAccess() failed");
|
|
106
174
|
}
|
|
175
|
+
auto ended = texture->get();
|
|
176
|
+
_accessed.erase(std::remove_if(_accessed.begin(), _accessed.end(),
|
|
177
|
+
[&](const wgpu::Texture &accessed) {
|
|
178
|
+
return accessed.Get() == ended.Get();
|
|
179
|
+
}),
|
|
180
|
+
_accessed.end());
|
|
107
181
|
|
|
108
182
|
// Copy each wgpu::SharedFence (ref-counted) into its own GPUSharedFence
|
|
109
183
|
// wrapper before `state` is destroyed.
|
|
110
184
|
jsi::Array fences(runtime, state.fenceCount);
|
|
111
185
|
for (size_t i = 0; i < state.fenceCount; i++) {
|
|
112
186
|
wgpu::SharedFence fence = state.fences[i];
|
|
113
|
-
auto wrapper =
|
|
187
|
+
auto wrapper =
|
|
188
|
+
std::make_shared<GPUSharedFence>(_device, std::move(fence), "");
|
|
114
189
|
jsi::Object entry(runtime);
|
|
115
190
|
entry.setProperty(runtime, "fence",
|
|
116
191
|
GPUSharedFence::create(runtime, std::move(wrapper)));
|
|
117
|
-
entry.setProperty(
|
|
118
|
-
|
|
192
|
+
entry.setProperty(
|
|
193
|
+
runtime, "signaledValue",
|
|
194
|
+
jsi::BigInt::fromUint64(runtime, state.signaledValues[i]));
|
|
119
195
|
fences.setValueAtIndex(runtime, i, std::move(entry));
|
|
120
196
|
}
|
|
121
197
|
|
|
@@ -23,16 +23,17 @@ class GPUSharedTextureMemory : public NativeObject<GPUSharedTextureMemory> {
|
|
|
23
23
|
public:
|
|
24
24
|
static constexpr const char *CLASS_NAME = "GPUSharedTextureMemory";
|
|
25
25
|
|
|
26
|
-
explicit GPUSharedTextureMemory(wgpu::
|
|
26
|
+
explicit GPUSharedTextureMemory(wgpu::Device device,
|
|
27
|
+
wgpu::SharedTextureMemory instance,
|
|
27
28
|
std::string label)
|
|
28
|
-
: NativeObject(CLASS_NAME),
|
|
29
|
-
_label(std::move(label)) {}
|
|
29
|
+
: NativeObject(CLASS_NAME), _device(std::move(device)),
|
|
30
|
+
_instance(std::move(instance)), _label(std::move(label)) {}
|
|
30
31
|
|
|
31
32
|
public:
|
|
32
33
|
std::string getBrand() { return CLASS_NAME; }
|
|
33
34
|
|
|
34
|
-
std::shared_ptr<GPUTexture>
|
|
35
|
-
|
|
35
|
+
std::shared_ptr<GPUTexture> createTexture(
|
|
36
|
+
std::optional<std::shared_ptr<GPUTextureDescriptor>> descriptor);
|
|
36
37
|
|
|
37
38
|
// Optional `fences` are wait fences: Dawn waits for each to reach its
|
|
38
39
|
// signaledValue before writing the surface. Throws on failure.
|
|
@@ -48,9 +49,17 @@ public:
|
|
|
48
49
|
std::string getLabel() { return _label; }
|
|
49
50
|
void setLabel(const std::string &label) {
|
|
50
51
|
_label = label;
|
|
51
|
-
_instance
|
|
52
|
+
if (_instance) {
|
|
53
|
+
_instance.SetLabel(_label.c_str());
|
|
54
|
+
}
|
|
52
55
|
}
|
|
53
56
|
|
|
57
|
+
// Releases the memory now (the imported native buffer and Dawn's import of
|
|
58
|
+
// it) rather than when the JS object is garbage collected. End the access
|
|
59
|
+
// first (destroying during one is a validation error), and destroy the
|
|
60
|
+
// textures created from it: they keep what they use until then.
|
|
61
|
+
void destroy();
|
|
62
|
+
|
|
54
63
|
static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
|
|
55
64
|
installGetter(runtime, prototype, "__brand",
|
|
56
65
|
&GPUSharedTextureMemory::getBrand);
|
|
@@ -60,6 +69,8 @@ public:
|
|
|
60
69
|
&GPUSharedTextureMemory::beginAccess);
|
|
61
70
|
installMethod(runtime, prototype, "endAccess",
|
|
62
71
|
&GPUSharedTextureMemory::endAccess);
|
|
72
|
+
installMethod(runtime, prototype, "destroy",
|
|
73
|
+
&GPUSharedTextureMemory::destroy);
|
|
63
74
|
installGetterSetter(runtime, prototype, "label",
|
|
64
75
|
&GPUSharedTextureMemory::getLabel,
|
|
65
76
|
&GPUSharedTextureMemory::setLabel);
|
|
@@ -68,7 +79,19 @@ public:
|
|
|
68
79
|
inline const wgpu::SharedTextureMemory get() { return _instance; }
|
|
69
80
|
|
|
70
81
|
private:
|
|
82
|
+
// Reports a use of the destroyed memory the way Dawn reports an invalid
|
|
83
|
+
// object: a validation error, caught by error scopes or else delivered to
|
|
84
|
+
// the device's uncapturederror event.
|
|
85
|
+
void injectDestroyedError(const char *method);
|
|
86
|
+
|
|
87
|
+
wgpu::Device _device;
|
|
71
88
|
wgpu::SharedTextureMemory _instance;
|
|
89
|
+
// Kept by destroy(): like Dawn, createTexture() describes the error texture
|
|
90
|
+
// it then returns with them.
|
|
91
|
+
wgpu::SharedTextureMemoryProperties _properties;
|
|
92
|
+
// The textures with an access begun and not yet ended, so destroy() can
|
|
93
|
+
// report an access left open. Dawn doesn't track that across a release.
|
|
94
|
+
std::vector<wgpu::Texture> _accessed;
|
|
72
95
|
std::string _label;
|
|
73
96
|
};
|
|
74
97
|
|
|
@@ -95,6 +95,7 @@ export interface GPUSharedFence {
|
|
|
95
95
|
readonly __brand: "GPUSharedFence";
|
|
96
96
|
label: string;
|
|
97
97
|
export(): GPUSharedFenceExportInfo;
|
|
98
|
+
destroy(): void;
|
|
98
99
|
}
|
|
99
100
|
export interface GPUSharedFenceState {
|
|
100
101
|
fence: GPUSharedFence;
|
|
@@ -114,6 +115,7 @@ export interface GPUSharedTextureMemory {
|
|
|
114
115
|
createTexture(descriptor?: GPUTextureDescriptor): GPUTexture;
|
|
115
116
|
beginAccess(texture: GPUTexture, initialized: boolean, fences?: GPUSharedFenceState[]): void;
|
|
116
117
|
endAccess(texture: GPUTexture): GPUSharedTextureMemoryEndAccessState;
|
|
118
|
+
destroy(): void;
|
|
117
119
|
}
|
|
118
120
|
export {};
|
|
119
121
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-webgpu",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "React Native WebGPU",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"clang-format": "^1.8.0",
|
|
83
83
|
"del-cli": "^5.1.0",
|
|
84
84
|
"eslint": "9.35.0",
|
|
85
|
-
"eslint-config-react-native-wcandillon": "5.0.
|
|
85
|
+
"eslint-config-react-native-wcandillon": "5.0.1",
|
|
86
86
|
"eslint-plugin-import": "2.32.0",
|
|
87
87
|
"eslint-plugin-jest": "^28.8.2",
|
|
88
88
|
"eslint-plugin-prettier": "^5.2.1",
|
package/src/types.ts
CHANGED
|
@@ -204,10 +204,17 @@ export interface GPUSharedFenceExportInfo {
|
|
|
204
204
|
export interface GPUSharedFence {
|
|
205
205
|
readonly __brand: "GPUSharedFence";
|
|
206
206
|
label: string;
|
|
207
|
+
// Throws, after a validation error says why, if the fence was destroyed or
|
|
208
|
+
// Dawn can't export it.
|
|
207
209
|
export(): GPUSharedFenceExportInfo;
|
|
210
|
+
// Releases the fence now (closing its sync fd on Android) rather than when
|
|
211
|
+
// the object is garbage collected. A later use is a validation error, and
|
|
212
|
+
// export() and beginAccess() then throw.
|
|
213
|
+
destroy(): void;
|
|
208
214
|
}
|
|
209
215
|
|
|
210
|
-
// A fence and the timeline value to wait for
|
|
216
|
+
// A fence and the timeline value to wait for. Binary fences (sync-fd on
|
|
217
|
+
// Vulkan) must use 1n: Dawn rejects any other value.
|
|
211
218
|
export interface GPUSharedFenceState {
|
|
212
219
|
fence: GPUSharedFence;
|
|
213
220
|
signaledValue: bigint;
|
|
@@ -252,4 +259,10 @@ export interface GPUSharedTextureMemory {
|
|
|
252
259
|
// Ends the access and returns the fences Dawn produced for it. Throws if the
|
|
253
260
|
// access could not be ended.
|
|
254
261
|
endAccess(texture: GPUTexture): GPUSharedTextureMemoryEndAccessState;
|
|
262
|
+
// Releases the memory (the imported native buffer) now rather than when the
|
|
263
|
+
// object is garbage collected. End the access first (a destroy() during one
|
|
264
|
+
// is a validation error, and the access stays open) and destroy the textures
|
|
265
|
+
// created from it. A later use is a validation error: createTexture() then
|
|
266
|
+
// returns an invalid texture, beginAccess() and endAccess() throw.
|
|
267
|
+
destroy(): void;
|
|
255
268
|
}
|