react-native-wgpu 0.2.2 → 0.2.4
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/apple/RNWGUIKit.h +1 -1
- package/cpp/dawn_logging.cpp +1 -1
- package/cpp/jsi/RNFHybridObject.h +6 -0
- package/cpp/jsi/RNFJSIConverter.h +6 -1
- package/cpp/rnwgpu/api/AsyncRunner.h +1 -1
- package/cpp/rnwgpu/api/GPUBindGroup.h +7 -0
- package/cpp/rnwgpu/api/GPUBindGroupLayout.h +7 -0
- package/cpp/rnwgpu/api/GPUBuffer.h +2 -0
- package/cpp/rnwgpu/api/GPUCanvasContext.cpp +1 -1
- package/cpp/rnwgpu/api/GPUComputePipeline.h +7 -0
- package/cpp/rnwgpu/api/GPUDevice.cpp +62 -41
- package/cpp/rnwgpu/api/GPUError.h +8 -5
- package/cpp/rnwgpu/api/GPUQuerySet.h +21 -0
- package/cpp/rnwgpu/api/GPUQueue.cpp +2 -1
- package/cpp/rnwgpu/api/GPURenderPassEncoder.cpp +3 -3
- package/cpp/rnwgpu/api/GPURenderPipeline.h +8 -0
- package/cpp/rnwgpu/api/GPUShaderModule.cpp +1 -1
- package/cpp/rnwgpu/api/GPUShaderModule.h +8 -0
- package/cpp/rnwgpu/api/GPUTexture.h +76 -0
- package/cpp/rnwgpu/api/ImageBitmap.h +2 -0
- package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts +2 -0
- package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts.map +1 -0
- package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
- package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
- package/libs/android/x86/libwebgpu_dawn.so +0 -0
- package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
- package/libs/apple/arm64_iphoneos/libwebgpu_dawn.a +0 -0
- package/libs/apple/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/arm64_xros/libwebgpu_dawn.a +0 -0
- package/libs/apple/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/iphonesimulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +13 -13
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64-simulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
- package/libs/apple/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
- package/package.json +1 -1
- package/src/__tests__/ErrorScope.spec.ts +92 -0
- package/libs/android/arm64-v8a/libwebgpu_dawn.a +0 -0
- package/libs/android/armeabi-v7a/libwebgpu_dawn.a +0 -0
- package/libs/android/x86/libwebgpu_dawn.a +0 -0
- package/libs/android/x86_64/libwebgpu_dawn.a +0 -0
package/apple/RNWGUIKit.h
CHANGED
package/cpp/dawn_logging.cpp
CHANGED
|
@@ -65,6 +65,12 @@ public:
|
|
|
65
65
|
*/
|
|
66
66
|
virtual std::string toString(jsi::Runtime& runtime);
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Get the memory pressure of this HostObject in bytes.
|
|
70
|
+
* This is used to inform the JavaScript runtime about memory usage for garbage collection.
|
|
71
|
+
*/
|
|
72
|
+
virtual size_t getMemoryPressure() { return 1024; }
|
|
73
|
+
|
|
68
74
|
private:
|
|
69
75
|
static constexpr auto TAG = "HybridObject";
|
|
70
76
|
int _instanceId = 1;
|
|
@@ -446,7 +446,12 @@ template <typename T> struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_h
|
|
|
446
446
|
throw jsi::JSError(runtime, "Cannot convert nullptr to HostObject<" + getFriendlyTypename() + ">!");
|
|
447
447
|
}
|
|
448
448
|
#endif
|
|
449
|
-
|
|
449
|
+
auto result = jsi::Object::createFromHostObject(runtime, arg);
|
|
450
|
+
auto memoryPressure = arg->getMemoryPressure();
|
|
451
|
+
if (memoryPressure > 0) {
|
|
452
|
+
result.setExternalMemoryPressure(runtime, memoryPressure);
|
|
453
|
+
}
|
|
454
|
+
return result;
|
|
450
455
|
}
|
|
451
456
|
};
|
|
452
457
|
|
|
@@ -37,6 +37,13 @@ public:
|
|
|
37
37
|
|
|
38
38
|
inline const wgpu::BindGroup get() { return _instance; }
|
|
39
39
|
|
|
40
|
+
size_t getMemoryPressure() override {
|
|
41
|
+
// Bind groups store resource bindings and descriptor state
|
|
42
|
+
// They reference buffers, textures, samplers, etc.
|
|
43
|
+
// Estimate: 1KB per bind group (descriptor tables and binding state)
|
|
44
|
+
return 1024;
|
|
45
|
+
}
|
|
46
|
+
|
|
40
47
|
private:
|
|
41
48
|
wgpu::BindGroup _instance;
|
|
42
49
|
std::string _label;
|
|
@@ -38,6 +38,13 @@ public:
|
|
|
38
38
|
|
|
39
39
|
inline const wgpu::BindGroupLayout get() { return _instance; }
|
|
40
40
|
|
|
41
|
+
size_t getMemoryPressure() override {
|
|
42
|
+
// Bind group layouts define the structure/schema for bind groups
|
|
43
|
+
// They store binding descriptors, types, and validation info
|
|
44
|
+
// Estimate: 512 bytes per layout (smaller than actual bind groups)
|
|
45
|
+
return 512;
|
|
46
|
+
}
|
|
47
|
+
|
|
41
48
|
private:
|
|
42
49
|
wgpu::BindGroupLayout _instance;
|
|
43
50
|
std::string _label;
|
|
@@ -45,6 +45,13 @@ public:
|
|
|
45
45
|
|
|
46
46
|
inline const wgpu::ComputePipeline get() { return _instance; }
|
|
47
47
|
|
|
48
|
+
size_t getMemoryPressure() override {
|
|
49
|
+
// Compute pipelines contain compiled compute shader state and
|
|
50
|
+
// driver-specific optimized code
|
|
51
|
+
// Estimate: 16KB for a typical compute pipeline (single compute shader)
|
|
52
|
+
return 16 * 1024;
|
|
53
|
+
}
|
|
54
|
+
|
|
48
55
|
private:
|
|
49
56
|
wgpu::ComputePipeline _instance;
|
|
50
57
|
std::string _label;
|
|
@@ -279,47 +279,68 @@ void GPUDevice::pushErrorScope(wgpu::ErrorFilter filter) {
|
|
|
279
279
|
|
|
280
280
|
std::future<std::variant<std::nullptr_t, std::shared_ptr<GPUError>>>
|
|
281
281
|
GPUDevice::popErrorScope() {
|
|
282
|
-
return
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
282
|
+
// Create a promise to return a future, but do the work synchronously on main
|
|
283
|
+
// thread
|
|
284
|
+
auto promise = std::make_shared<
|
|
285
|
+
std::promise<std::variant<std::nullptr_t, std::shared_ptr<GPUError>>>>();
|
|
286
|
+
auto future = promise->get_future();
|
|
287
|
+
|
|
288
|
+
std::variant<std::nullptr_t, std::shared_ptr<GPUError>> result = nullptr;
|
|
289
|
+
|
|
290
|
+
auto wgpu_future = _instance.PopErrorScope(
|
|
291
|
+
wgpu::CallbackMode::WaitAnyOnly,
|
|
292
|
+
[&result](wgpu::PopErrorScopeStatus status, wgpu::ErrorType type,
|
|
293
|
+
wgpu::StringView message) {
|
|
294
|
+
switch (status) {
|
|
295
|
+
case wgpu::PopErrorScopeStatus::Error:
|
|
296
|
+
// PopErrorScope itself failed, e.g. the error scope stack was empty.
|
|
297
|
+
return;
|
|
298
|
+
case wgpu::PopErrorScopeStatus::CallbackCancelled:
|
|
299
|
+
// The instance has been dropped. Shouldn't happen except maybe during
|
|
300
|
+
// shutdown.
|
|
301
|
+
return;
|
|
302
|
+
case wgpu::PopErrorScopeStatus::Success:
|
|
303
|
+
// This is the only case where `type` is set to a meaningful value.
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
switch (type) {
|
|
307
|
+
case wgpu::ErrorType::NoError:
|
|
308
|
+
break;
|
|
309
|
+
case wgpu::ErrorType::OutOfMemory: {
|
|
310
|
+
result = std::make_shared<GPUError>(wgpu::ErrorType::OutOfMemory,
|
|
311
|
+
std::string(message));
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
case wgpu::ErrorType::Validation: {
|
|
315
|
+
result = std::make_shared<GPUError>(wgpu::ErrorType::Validation,
|
|
316
|
+
std::string(message));
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
case wgpu::ErrorType::Internal: {
|
|
320
|
+
result = std::make_shared<GPUError>(wgpu::ErrorType::Internal,
|
|
321
|
+
std::string(message));
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
case wgpu::ErrorType::Unknown:
|
|
325
|
+
result = std::make_shared<GPUError>(wgpu::ErrorType::Unknown,
|
|
326
|
+
std::string(message));
|
|
327
|
+
break;
|
|
328
|
+
default:
|
|
329
|
+
throw std::runtime_error(
|
|
330
|
+
"unhandled error type (" +
|
|
331
|
+
std::to_string(
|
|
332
|
+
static_cast<std::underlying_type<wgpu::ErrorType>::type>(
|
|
333
|
+
type)) +
|
|
334
|
+
")");
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// Wait synchronously on main thread - both push and pop now on same thread
|
|
340
|
+
_async->instance->WaitAny(wgpu_future, UINT64_MAX);
|
|
341
|
+
|
|
342
|
+
promise->set_value(result);
|
|
343
|
+
return future;
|
|
323
344
|
}
|
|
324
345
|
|
|
325
346
|
std::unordered_set<std::string> GPUDevice::getFeatures() {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include <memory>
|
|
4
|
+
#include <utility>
|
|
5
|
+
#include <string>
|
|
4
6
|
|
|
5
7
|
#include "webgpu/webgpu_cpp.h"
|
|
6
8
|
|
|
@@ -12,11 +14,11 @@ namespace rnwgpu {
|
|
|
12
14
|
class GPUError {
|
|
13
15
|
|
|
14
16
|
public:
|
|
15
|
-
GPUError(wgpu::ErrorType aType,
|
|
16
|
-
: type(aType), message(aMessage) {}
|
|
17
|
+
GPUError(wgpu::ErrorType aType, std::string aMessage)
|
|
18
|
+
: type(aType), message(std::move(aMessage)) {}
|
|
17
19
|
|
|
18
20
|
wgpu::ErrorType type;
|
|
19
|
-
|
|
21
|
+
std::string message;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
} // namespace rnwgpu
|
|
@@ -33,8 +35,9 @@ template <> struct JSIConverter<std::shared_ptr<rnwgpu::GPUError>> {
|
|
|
33
35
|
static jsi::Value toJSI(jsi::Runtime &runtime,
|
|
34
36
|
std::shared_ptr<rnwgpu::GPUError> arg) {
|
|
35
37
|
jsi::Object result(runtime);
|
|
36
|
-
result.setProperty(
|
|
37
|
-
|
|
38
|
+
result.setProperty(
|
|
39
|
+
runtime, "message",
|
|
40
|
+
jsi::String::createFromUtf8(runtime, arg->message.c_str()));
|
|
38
41
|
return result;
|
|
39
42
|
}
|
|
40
43
|
};
|
|
@@ -44,6 +44,27 @@ public:
|
|
|
44
44
|
|
|
45
45
|
inline const wgpu::QuerySet get() { return _instance; }
|
|
46
46
|
|
|
47
|
+
size_t getMemoryPressure() override {
|
|
48
|
+
uint32_t count = getCount();
|
|
49
|
+
wgpu::QueryType type = getType();
|
|
50
|
+
|
|
51
|
+
// Estimate bytes per query based on type
|
|
52
|
+
size_t bytesPerQuery = 8; // Default estimate
|
|
53
|
+
switch (type) {
|
|
54
|
+
case wgpu::QueryType::Occlusion:
|
|
55
|
+
bytesPerQuery = 8; // 64-bit counter
|
|
56
|
+
break;
|
|
57
|
+
case wgpu::QueryType::Timestamp:
|
|
58
|
+
bytesPerQuery = 8; // 64-bit timestamp
|
|
59
|
+
break;
|
|
60
|
+
default:
|
|
61
|
+
bytesPerQuery = 8; // Safe default
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return static_cast<size_t>(count) * bytesPerQuery;
|
|
66
|
+
}
|
|
67
|
+
|
|
47
68
|
private:
|
|
48
69
|
wgpu::QuerySet _instance;
|
|
49
70
|
std::string _label;
|
|
@@ -40,7 +40,8 @@ void GPUQueue::writeBuffer(std::shared_ptr<GPUBuffer> buffer,
|
|
|
40
40
|
|
|
41
41
|
// Note that in the JS semantics of WebGPU, writeBuffer works in number of
|
|
42
42
|
// elements of the typed arrays.
|
|
43
|
-
if (dataOffsetElements >
|
|
43
|
+
if (dataOffsetElements >
|
|
44
|
+
static_cast<uint64_t>(src.size / src.bytesPerElement)) {
|
|
44
45
|
throw std::runtime_error("dataOffset is larger than data's size.");
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#include <vector>
|
|
2
|
-
#include <string>
|
|
3
1
|
#include <memory>
|
|
2
|
+
#include <string>
|
|
3
|
+
#include <vector>
|
|
4
4
|
|
|
5
5
|
#include "GPURenderPassEncoder.h"
|
|
6
6
|
#include "Convertors.h"
|
|
@@ -162,4 +162,4 @@ void GPURenderPassEncoder::drawIndexedIndirect(
|
|
|
162
162
|
_instance.DrawIndexedIndirect(b, indirectOffset);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
} // namespace rnwgpu
|
|
165
|
+
} // namespace rnwgpu
|
|
@@ -44,6 +44,14 @@ public:
|
|
|
44
44
|
|
|
45
45
|
inline const wgpu::RenderPipeline get() { return _instance; }
|
|
46
46
|
|
|
47
|
+
size_t getMemoryPressure() override {
|
|
48
|
+
// Render pipelines contain compiled shader state, vertex/fragment shaders,
|
|
49
|
+
// render state, and driver-specific optimized code
|
|
50
|
+
// Estimate: 24KB for a typical render pipeline with vertex + fragment
|
|
51
|
+
// shaders
|
|
52
|
+
return 24 * 1024;
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
private:
|
|
48
56
|
wgpu::RenderPipeline _instance;
|
|
49
57
|
std::string _label;
|
|
@@ -48,6 +48,14 @@ public:
|
|
|
48
48
|
|
|
49
49
|
inline const wgpu::ShaderModule get() { return _instance; }
|
|
50
50
|
|
|
51
|
+
size_t getMemoryPressure() override {
|
|
52
|
+
// Estimate memory usage for compiled shader module
|
|
53
|
+
// Shaders can vary widely, but a reasonable estimate is 8-16KB for typical
|
|
54
|
+
// shaders Complex shaders (with many uniforms, textures, or computations)
|
|
55
|
+
// can be much larger
|
|
56
|
+
return 12 * 1024; // 12KB estimate for average shader
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
private:
|
|
52
60
|
wgpu::ShaderModule _instance;
|
|
53
61
|
std::shared_ptr<AsyncRunner> _async;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include <algorithm>
|
|
3
4
|
#include <memory>
|
|
4
5
|
#include <string>
|
|
5
6
|
|
|
@@ -64,6 +65,81 @@ public:
|
|
|
64
65
|
|
|
65
66
|
inline const wgpu::Texture get() { return _instance; }
|
|
66
67
|
|
|
68
|
+
size_t getMemoryPressure() override {
|
|
69
|
+
// Calculate approximate memory usage based on texture properties
|
|
70
|
+
uint32_t width = getWidth();
|
|
71
|
+
uint32_t height = getHeight();
|
|
72
|
+
uint32_t depthOrArrayLayers = getDepthOrArrayLayers();
|
|
73
|
+
uint32_t mipLevelCount = getMipLevelCount();
|
|
74
|
+
uint32_t sampleCount = getSampleCount();
|
|
75
|
+
|
|
76
|
+
// Estimate bytes per pixel based on format
|
|
77
|
+
// This is a simplified estimate - actual values depend on the specific
|
|
78
|
+
// format
|
|
79
|
+
size_t bytesPerPixel = 4; // Default to RGBA8 format
|
|
80
|
+
wgpu::TextureFormat format = getFormat();
|
|
81
|
+
switch (format) {
|
|
82
|
+
case wgpu::TextureFormat::R8Unorm:
|
|
83
|
+
case wgpu::TextureFormat::R8Snorm:
|
|
84
|
+
case wgpu::TextureFormat::R8Uint:
|
|
85
|
+
case wgpu::TextureFormat::R8Sint:
|
|
86
|
+
bytesPerPixel = 1;
|
|
87
|
+
break;
|
|
88
|
+
case wgpu::TextureFormat::R16Uint:
|
|
89
|
+
case wgpu::TextureFormat::R16Sint:
|
|
90
|
+
case wgpu::TextureFormat::R16Float:
|
|
91
|
+
case wgpu::TextureFormat::RG8Unorm:
|
|
92
|
+
case wgpu::TextureFormat::RG8Snorm:
|
|
93
|
+
case wgpu::TextureFormat::RG8Uint:
|
|
94
|
+
case wgpu::TextureFormat::RG8Sint:
|
|
95
|
+
bytesPerPixel = 2;
|
|
96
|
+
break;
|
|
97
|
+
case wgpu::TextureFormat::RGBA8Unorm:
|
|
98
|
+
case wgpu::TextureFormat::RGBA8UnormSrgb:
|
|
99
|
+
case wgpu::TextureFormat::RGBA8Snorm:
|
|
100
|
+
case wgpu::TextureFormat::RGBA8Uint:
|
|
101
|
+
case wgpu::TextureFormat::RGBA8Sint:
|
|
102
|
+
case wgpu::TextureFormat::BGRA8Unorm:
|
|
103
|
+
case wgpu::TextureFormat::BGRA8UnormSrgb:
|
|
104
|
+
case wgpu::TextureFormat::RGB10A2Unorm:
|
|
105
|
+
case wgpu::TextureFormat::R32Float:
|
|
106
|
+
case wgpu::TextureFormat::R32Uint:
|
|
107
|
+
case wgpu::TextureFormat::R32Sint:
|
|
108
|
+
case wgpu::TextureFormat::RG16Uint:
|
|
109
|
+
case wgpu::TextureFormat::RG16Sint:
|
|
110
|
+
case wgpu::TextureFormat::RG16Float:
|
|
111
|
+
bytesPerPixel = 4;
|
|
112
|
+
break;
|
|
113
|
+
case wgpu::TextureFormat::RG32Float:
|
|
114
|
+
case wgpu::TextureFormat::RG32Uint:
|
|
115
|
+
case wgpu::TextureFormat::RG32Sint:
|
|
116
|
+
case wgpu::TextureFormat::RGBA16Uint:
|
|
117
|
+
case wgpu::TextureFormat::RGBA16Sint:
|
|
118
|
+
case wgpu::TextureFormat::RGBA16Float:
|
|
119
|
+
bytesPerPixel = 8;
|
|
120
|
+
break;
|
|
121
|
+
case wgpu::TextureFormat::RGBA32Float:
|
|
122
|
+
case wgpu::TextureFormat::RGBA32Uint:
|
|
123
|
+
case wgpu::TextureFormat::RGBA32Sint:
|
|
124
|
+
bytesPerPixel = 16;
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
bytesPerPixel = 4; // Safe default
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Calculate total memory for all mip levels
|
|
132
|
+
size_t totalMemory = 0;
|
|
133
|
+
for (uint32_t mip = 0; mip < mipLevelCount; ++mip) {
|
|
134
|
+
uint32_t mipWidth = std::max(1u, width >> mip);
|
|
135
|
+
uint32_t mipHeight = std::max(1u, height >> mip);
|
|
136
|
+
totalMemory += static_cast<size_t>(mipWidth) * mipHeight *
|
|
137
|
+
depthOrArrayLayers * bytesPerPixel * sampleCount;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return totalMemory;
|
|
141
|
+
}
|
|
142
|
+
|
|
67
143
|
private:
|
|
68
144
|
wgpu::Texture _instance;
|
|
69
145
|
std::string _label;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorScope.spec.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/ErrorScope.spec.ts"],"names":[],"mappings":""}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<key>BinaryPath</key>
|
|
9
9
|
<string>libwebgpu_dawn.a</string>
|
|
10
10
|
<key>LibraryIdentifier</key>
|
|
11
|
-
<string>
|
|
11
|
+
<string>macos-arm64_x86_64</string>
|
|
12
12
|
<key>LibraryPath</key>
|
|
13
13
|
<string>libwebgpu_dawn.a</string>
|
|
14
14
|
<key>SupportedArchitectures</key>
|
|
@@ -17,15 +17,13 @@
|
|
|
17
17
|
<string>x86_64</string>
|
|
18
18
|
</array>
|
|
19
19
|
<key>SupportedPlatform</key>
|
|
20
|
-
<string>
|
|
21
|
-
<key>SupportedPlatformVariant</key>
|
|
22
|
-
<string>simulator</string>
|
|
20
|
+
<string>macos</string>
|
|
23
21
|
</dict>
|
|
24
22
|
<dict>
|
|
25
23
|
<key>BinaryPath</key>
|
|
26
24
|
<string>libwebgpu_dawn.a</string>
|
|
27
25
|
<key>LibraryIdentifier</key>
|
|
28
|
-
<string>
|
|
26
|
+
<string>ios-arm64_x86_64-simulator</string>
|
|
29
27
|
<key>LibraryPath</key>
|
|
30
28
|
<string>libwebgpu_dawn.a</string>
|
|
31
29
|
<key>SupportedArchitectures</key>
|
|
@@ -34,13 +32,15 @@
|
|
|
34
32
|
<string>x86_64</string>
|
|
35
33
|
</array>
|
|
36
34
|
<key>SupportedPlatform</key>
|
|
37
|
-
<string>
|
|
35
|
+
<string>ios</string>
|
|
36
|
+
<key>SupportedPlatformVariant</key>
|
|
37
|
+
<string>simulator</string>
|
|
38
38
|
</dict>
|
|
39
39
|
<dict>
|
|
40
40
|
<key>BinaryPath</key>
|
|
41
41
|
<string>libwebgpu_dawn.a</string>
|
|
42
42
|
<key>LibraryIdentifier</key>
|
|
43
|
-
<string>
|
|
43
|
+
<string>xros-arm64-simulator</string>
|
|
44
44
|
<key>LibraryPath</key>
|
|
45
45
|
<string>libwebgpu_dawn.a</string>
|
|
46
46
|
<key>SupportedArchitectures</key>
|
|
@@ -48,13 +48,15 @@
|
|
|
48
48
|
<string>arm64</string>
|
|
49
49
|
</array>
|
|
50
50
|
<key>SupportedPlatform</key>
|
|
51
|
-
<string>
|
|
51
|
+
<string>xros</string>
|
|
52
|
+
<key>SupportedPlatformVariant</key>
|
|
53
|
+
<string>simulator</string>
|
|
52
54
|
</dict>
|
|
53
55
|
<dict>
|
|
54
56
|
<key>BinaryPath</key>
|
|
55
57
|
<string>libwebgpu_dawn.a</string>
|
|
56
58
|
<key>LibraryIdentifier</key>
|
|
57
|
-
<string>xros-arm64
|
|
59
|
+
<string>xros-arm64</string>
|
|
58
60
|
<key>LibraryPath</key>
|
|
59
61
|
<string>libwebgpu_dawn.a</string>
|
|
60
62
|
<key>SupportedArchitectures</key>
|
|
@@ -63,14 +65,12 @@
|
|
|
63
65
|
</array>
|
|
64
66
|
<key>SupportedPlatform</key>
|
|
65
67
|
<string>xros</string>
|
|
66
|
-
<key>SupportedPlatformVariant</key>
|
|
67
|
-
<string>simulator</string>
|
|
68
68
|
</dict>
|
|
69
69
|
<dict>
|
|
70
70
|
<key>BinaryPath</key>
|
|
71
71
|
<string>libwebgpu_dawn.a</string>
|
|
72
72
|
<key>LibraryIdentifier</key>
|
|
73
|
-
<string>
|
|
73
|
+
<string>ios-arm64</string>
|
|
74
74
|
<key>LibraryPath</key>
|
|
75
75
|
<string>libwebgpu_dawn.a</string>
|
|
76
76
|
<key>SupportedArchitectures</key>
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
<string>arm64</string>
|
|
79
79
|
</array>
|
|
80
80
|
<key>SupportedPlatform</key>
|
|
81
|
-
<string>
|
|
81
|
+
<string>ios</string>
|
|
82
82
|
</dict>
|
|
83
83
|
</array>
|
|
84
84
|
<key>CFBundlePackageType</key>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { client } from "./setup";
|
|
2
|
+
|
|
3
|
+
describe("Error Scope", () => {
|
|
4
|
+
it("should capture validation error when creating sampler with invalid maxAnisotropy", async () => {
|
|
5
|
+
const result = await client.eval(({ device }) => {
|
|
6
|
+
device.pushErrorScope("validation");
|
|
7
|
+
device.createSampler({
|
|
8
|
+
maxAnisotropy: 0, // Invalid, maxAnisotropy must be at least 1.
|
|
9
|
+
});
|
|
10
|
+
return device.popErrorScope().then((error) => {
|
|
11
|
+
if (error) {
|
|
12
|
+
return {
|
|
13
|
+
hasError: true,
|
|
14
|
+
message: error.message,
|
|
15
|
+
messageLength: error.message.length,
|
|
16
|
+
messageNotEmpty: error.message.length > 0,
|
|
17
|
+
};
|
|
18
|
+
} else {
|
|
19
|
+
return {
|
|
20
|
+
hasError: false,
|
|
21
|
+
message: "",
|
|
22
|
+
messageLength: 0,
|
|
23
|
+
messageNotEmpty: false,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
expect(result.hasError).toBe(true);
|
|
30
|
+
expect(result.messageNotEmpty).toBe(true);
|
|
31
|
+
expect(result.messageLength).toBeGreaterThan(0);
|
|
32
|
+
});
|
|
33
|
+
it("should capture and return error messages from popErrorScope", async () => {
|
|
34
|
+
const result = await client.eval(({ device }) => {
|
|
35
|
+
// Invalid WGSL shader with syntax error (missing closing parenthesis)
|
|
36
|
+
const invalidShaderWGSL = `@fragment
|
|
37
|
+
fn main() -> @location(0) vec4f {
|
|
38
|
+
return vec4(1.0, 0.0, 0.0, 1.0;
|
|
39
|
+
}`;
|
|
40
|
+
device.pushErrorScope("validation");
|
|
41
|
+
// This should generate a validation error due to syntax error
|
|
42
|
+
device.createShaderModule({
|
|
43
|
+
code: invalidShaderWGSL,
|
|
44
|
+
});
|
|
45
|
+
return device.popErrorScope().then((error) => {
|
|
46
|
+
if (error) {
|
|
47
|
+
return {
|
|
48
|
+
hasError: true,
|
|
49
|
+
message: error.message,
|
|
50
|
+
messageLength: error.message.length,
|
|
51
|
+
messageNotEmpty: error.message.length > 0,
|
|
52
|
+
messageContainsExpected:
|
|
53
|
+
error.message.includes("expected") ||
|
|
54
|
+
error.message.includes("error") ||
|
|
55
|
+
error.message.includes("parsing"),
|
|
56
|
+
};
|
|
57
|
+
} else {
|
|
58
|
+
return {
|
|
59
|
+
hasError: false,
|
|
60
|
+
message: "",
|
|
61
|
+
messageLength: 0,
|
|
62
|
+
messageNotEmpty: false,
|
|
63
|
+
messageContainsExpected: false,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
expect(result.hasError).toBe(true);
|
|
69
|
+
expect(result.messageNotEmpty).toBe(true);
|
|
70
|
+
expect(result.messageLength).toBeGreaterThan(0);
|
|
71
|
+
// The error message should contain some indication that it's a parsing error
|
|
72
|
+
expect(result.messageContainsExpected).toBe(true);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("should return null when no error occurs", async () => {
|
|
76
|
+
const result = await client.eval(({ device, shaders: { redFragWGSL } }) => {
|
|
77
|
+
device.pushErrorScope("validation");
|
|
78
|
+
// This should not generate any errors
|
|
79
|
+
device.createShaderModule({
|
|
80
|
+
code: redFragWGSL,
|
|
81
|
+
});
|
|
82
|
+
return device.popErrorScope().then((error) => {
|
|
83
|
+
return {
|
|
84
|
+
hasError: error !== null,
|
|
85
|
+
error: error,
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
expect(result.hasError).toBe(false);
|
|
90
|
+
expect(result.error).toBe(null);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|