react-native-wgpu 0.1.6 → 0.1.8
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/GPUDevice.cpp +5 -3
- package/lib/commonjs/Canvas.js.map +1 -1
- package/lib/commonjs/Offscreen.js +121 -0
- package/lib/commonjs/Offscreen.js.map +1 -0
- package/lib/commonjs/index.js +12 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/Canvas.js.map +1 -1
- package/lib/module/Offscreen.js +114 -0
- package/lib/module/Offscreen.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/lib/commonjs/Offscreen.d.ts +31 -0
- package/lib/typescript/lib/commonjs/Offscreen.d.ts.map +1 -0
- package/lib/typescript/lib/module/Offscreen.d.ts +30 -0
- package/lib/typescript/lib/module/Offscreen.d.ts.map +1 -0
- package/lib/typescript/lib/module/index.d.ts +1 -0
- package/lib/typescript/src/Canvas.d.ts +3 -3
- package/lib/typescript/src/Canvas.d.ts.map +1 -1
- package/lib/typescript/src/Offscreen.d.ts +26 -0
- package/lib/typescript/src/Offscreen.d.ts.map +1 -0
- package/lib/typescript/src/__tests__/setup.d.ts +5 -4
- package/lib/typescript/src/__tests__/setup.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- 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/{libwebgpu_dawn.a → iphonesimulator/libwebgpu_dawn.a} +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +45 -0
- 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_macosx.xcframework → libwebgpu_dawn.xcframework}/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
- package/libs/apple/{libwebgpu_dawn_visionos.xcframework → libwebgpu_dawn.xcframework}/xros-arm64/libwebgpu_dawn.a +0 -0
- package/libs/apple/{x86_64_xrsimulator → 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 +3 -2
- package/react-native-wgpu.podspec +51 -0
- package/src/Canvas.tsx +4 -4
- package/src/Offscreen.ts +160 -0
- package/src/__tests__/ExternalTexture.spec.ts +4 -4
- package/src/__tests__/Texture.spec.ts +8 -2
- package/src/__tests__/demos/ABuffer.spec.ts +17 -12
- package/src/__tests__/demos/Blur.spec.ts +2 -1
- package/src/__tests__/demos/Cube.spec.ts +16 -12
- package/src/__tests__/demos/FractalCube.spec.ts +6 -5
- package/src/__tests__/demos/OcclusionQuery.spec.ts +3 -3
- package/src/__tests__/demos/RenderBundles.spec.ts +4 -3
- package/src/__tests__/demos/Triangle.spec.ts +27 -9
- package/src/__tests__/setup.ts +25 -10
- package/src/index.tsx +1 -0
- package/lib/typescript/src/__tests__/components/DrawingContext.d.ts +0 -12
- package/lib/typescript/src/__tests__/components/DrawingContext.d.ts.map +0 -1
- package/libs/apple/libwebgpu_dawn_macosx.xcframework/Info.plist +0 -28
- package/libs/apple/libwebgpu_dawn_visionos.a +0 -0
- package/libs/apple/libwebgpu_dawn_visionos.xcframework/Info.plist +0 -44
- package/libs/apple/libwebgpu_dawn_visionos.xcframework/xros-arm64_x86_64-simulator/libwebgpu_dawn_visionos.a +0 -0
- package/src/__tests__/components/DrawingContext.ts +0 -11
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -4,6 +4,36 @@
|
|
|
4
4
|
<dict>
|
|
5
5
|
<key>AvailableLibraries</key>
|
|
6
6
|
<array>
|
|
7
|
+
<dict>
|
|
8
|
+
<key>BinaryPath</key>
|
|
9
|
+
<string>libwebgpu_dawn.a</string>
|
|
10
|
+
<key>LibraryIdentifier</key>
|
|
11
|
+
<string>xros-arm64</string>
|
|
12
|
+
<key>LibraryPath</key>
|
|
13
|
+
<string>libwebgpu_dawn.a</string>
|
|
14
|
+
<key>SupportedArchitectures</key>
|
|
15
|
+
<array>
|
|
16
|
+
<string>arm64</string>
|
|
17
|
+
</array>
|
|
18
|
+
<key>SupportedPlatform</key>
|
|
19
|
+
<string>xros</string>
|
|
20
|
+
</dict>
|
|
21
|
+
<dict>
|
|
22
|
+
<key>BinaryPath</key>
|
|
23
|
+
<string>libwebgpu_dawn.a</string>
|
|
24
|
+
<key>LibraryIdentifier</key>
|
|
25
|
+
<string>xros-arm64-simulator</string>
|
|
26
|
+
<key>LibraryPath</key>
|
|
27
|
+
<string>libwebgpu_dawn.a</string>
|
|
28
|
+
<key>SupportedArchitectures</key>
|
|
29
|
+
<array>
|
|
30
|
+
<string>arm64</string>
|
|
31
|
+
</array>
|
|
32
|
+
<key>SupportedPlatform</key>
|
|
33
|
+
<string>xros</string>
|
|
34
|
+
<key>SupportedPlatformVariant</key>
|
|
35
|
+
<string>simulator</string>
|
|
36
|
+
</dict>
|
|
7
37
|
<dict>
|
|
8
38
|
<key>BinaryPath</key>
|
|
9
39
|
<string>libwebgpu_dawn.a</string>
|
|
@@ -35,6 +65,21 @@
|
|
|
35
65
|
<key>SupportedPlatform</key>
|
|
36
66
|
<string>ios</string>
|
|
37
67
|
</dict>
|
|
68
|
+
<dict>
|
|
69
|
+
<key>BinaryPath</key>
|
|
70
|
+
<string>libwebgpu_dawn.a</string>
|
|
71
|
+
<key>LibraryIdentifier</key>
|
|
72
|
+
<string>macos-arm64_x86_64</string>
|
|
73
|
+
<key>LibraryPath</key>
|
|
74
|
+
<string>libwebgpu_dawn.a</string>
|
|
75
|
+
<key>SupportedArchitectures</key>
|
|
76
|
+
<array>
|
|
77
|
+
<string>arm64</string>
|
|
78
|
+
<string>x86_64</string>
|
|
79
|
+
</array>
|
|
80
|
+
<key>SupportedPlatform</key>
|
|
81
|
+
<string>macos</string>
|
|
82
|
+
</dict>
|
|
38
83
|
</array>
|
|
39
84
|
<key>CFBundlePackageType</key>
|
|
40
85
|
<string>XFWK</string>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-wgpu",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "React Native WebGPU",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"android/src/**",
|
|
17
17
|
"cpp/**/*.{h,cpp}",
|
|
18
18
|
"ios/**",
|
|
19
|
-
"libs/**"
|
|
19
|
+
"libs/**",
|
|
20
|
+
"*.podspec"
|
|
20
21
|
],
|
|
21
22
|
"scripts": {
|
|
22
23
|
"test": "jest -i",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
|
|
5
|
+
|
|
6
|
+
Pod::Spec.new do |s|
|
|
7
|
+
s.name = "react-native-wgpu"
|
|
8
|
+
s.version = package["version"]
|
|
9
|
+
s.summary = package["description"]
|
|
10
|
+
s.homepage = package["homepage"]
|
|
11
|
+
s.license = package["license"]
|
|
12
|
+
s.authors = package["author"]
|
|
13
|
+
|
|
14
|
+
s.platforms = { :ios => min_ios_version_supported, :visionos => "1.0" }
|
|
15
|
+
s.source = { :git => "https://github.com/wcandillon/react-native-webgpu.git", :tag => "#{s.version}" }
|
|
16
|
+
|
|
17
|
+
s.source_files = [
|
|
18
|
+
"ios/**/*.{h,c,cc,cpp,m,mm,swift}",
|
|
19
|
+
"cpp/**/*.{h,cpp}"
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
s.vendored_frameworks = 'libs/apple/libwebgpu_dawn.xcframework'
|
|
23
|
+
|
|
24
|
+
s.pod_target_xcconfig = {
|
|
25
|
+
'HEADER_SEARCH_PATHS' => '$(PODS_TARGET_SRCROOT)/cpp',
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
29
|
+
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
|
30
|
+
if respond_to?(:install_modules_dependencies, true)
|
|
31
|
+
install_modules_dependencies(s)
|
|
32
|
+
else
|
|
33
|
+
s.dependency "React-Core"
|
|
34
|
+
|
|
35
|
+
# Don't install the dependencies when we run `pod install` in the old architecture.
|
|
36
|
+
if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
|
|
37
|
+
s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
|
|
38
|
+
s.pod_target_xcconfig = {
|
|
39
|
+
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
|
|
40
|
+
"OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
|
|
41
|
+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
|
|
42
|
+
}
|
|
43
|
+
s.dependency "React-RCTFabric"
|
|
44
|
+
s.dependency "React-Codegen"
|
|
45
|
+
s.dependency "RCT-Folly"
|
|
46
|
+
s.dependency "RCTRequired"
|
|
47
|
+
s.dependency "RCTTypeSafety"
|
|
48
|
+
s.dependency "ReactCommon/turbomodule/core"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
package/src/Canvas.tsx
CHANGED
|
@@ -15,7 +15,7 @@ declare global {
|
|
|
15
15
|
// eslint-disable-next-line no-var
|
|
16
16
|
var RNWebGPU: {
|
|
17
17
|
gpu: GPU;
|
|
18
|
-
MakeWebGPUCanvasContext: (nativeCanvas: NativeCanvas) =>
|
|
18
|
+
MakeWebGPUCanvasContext: (nativeCanvas: NativeCanvas) => RNCanvasContext;
|
|
19
19
|
DecodeToUTF8: (buffer: NodeJS.ArrayBufferView | ArrayBuffer) => string;
|
|
20
20
|
createImageBitmap: typeof createImageBitmap;
|
|
21
21
|
};
|
|
@@ -34,12 +34,12 @@ export interface NativeCanvas {
|
|
|
34
34
|
global.__WebGPUContextRegistry = {};
|
|
35
35
|
const WebGPUContextRegistry = global.__WebGPUContextRegistry;
|
|
36
36
|
|
|
37
|
-
type
|
|
37
|
+
export type RNCanvasContext = GPUCanvasContext & {
|
|
38
38
|
present: () => void;
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export interface CanvasRef {
|
|
42
|
-
getContext(contextName: "webgpu"):
|
|
42
|
+
getContext(contextName: "webgpu"): RNCanvasContext | null;
|
|
43
43
|
getNativeSurface: () => NativeCanvas;
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -51,7 +51,7 @@ export const Canvas = forwardRef<CanvasRef, ViewProps>((props, ref) => {
|
|
|
51
51
|
WebGPUNativeModule.createSurfaceContext(contextId);
|
|
52
52
|
return WebGPUContextRegistry[contextId];
|
|
53
53
|
},
|
|
54
|
-
getContext(contextName: "webgpu"):
|
|
54
|
+
getContext(contextName: "webgpu"): RNCanvasContext | null {
|
|
55
55
|
if (contextName !== "webgpu") {
|
|
56
56
|
throw new Error(`[WebGPU] Unsupported context: ${contextName}`);
|
|
57
57
|
}
|
package/src/Offscreen.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
export class GPUOffscreenCanvas implements OffscreenCanvas {
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
oncontextlost: ((this: OffscreenCanvas, ev: Event) => any) | null = null;
|
|
6
|
+
oncontextrestored: ((this: OffscreenCanvas, ev: Event) => any) | null = null;
|
|
7
|
+
|
|
8
|
+
private context: GPUOffscreenCanvasContext;
|
|
9
|
+
|
|
10
|
+
constructor(width: number, height: number) {
|
|
11
|
+
this.width = width;
|
|
12
|
+
this.height = height;
|
|
13
|
+
this.context = new GPUOffscreenCanvasContext(this);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
convertToBlob(_options?: ImageEncodeOptions): Promise<Blob> {
|
|
17
|
+
// Implementation for converting the canvas content to a Blob
|
|
18
|
+
throw new Error("Method not implemented.");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Overloaded method signatures
|
|
22
|
+
getContext(
|
|
23
|
+
contextId: "2d",
|
|
24
|
+
options?: any,
|
|
25
|
+
): OffscreenCanvasRenderingContext2D | null;
|
|
26
|
+
getContext(
|
|
27
|
+
contextId: "bitmaprenderer",
|
|
28
|
+
options?: any,
|
|
29
|
+
): ImageBitmapRenderingContext | null;
|
|
30
|
+
getContext(contextId: "webgl", options?: any): WebGLRenderingContext | null;
|
|
31
|
+
getContext(contextId: "webgl2", options?: any): WebGL2RenderingContext | null;
|
|
32
|
+
getContext(
|
|
33
|
+
contextId: OffscreenRenderingContextId,
|
|
34
|
+
options?: any,
|
|
35
|
+
): OffscreenRenderingContext | null;
|
|
36
|
+
getContext(contextId: "webgpu"): GPUCanvasContext | null;
|
|
37
|
+
getContext(
|
|
38
|
+
contextId: unknown,
|
|
39
|
+
_options?: any,
|
|
40
|
+
): OffscreenRenderingContext | GPUCanvasContext | null {
|
|
41
|
+
if (contextId === "webgpu") {
|
|
42
|
+
return this.context;
|
|
43
|
+
}
|
|
44
|
+
// Implement other context types if necessary
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
transferToImageBitmap(): ImageBitmap {
|
|
49
|
+
// Implementation for transferring the canvas content to an ImageBitmap
|
|
50
|
+
throw new Error("Method not implemented.");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
addEventListener<K extends keyof OffscreenCanvasEventMap>(
|
|
54
|
+
_type: K,
|
|
55
|
+
_listener: (this: OffscreenCanvas, ev: OffscreenCanvasEventMap[K]) => any,
|
|
56
|
+
_options?: boolean | AddEventListenerOptions,
|
|
57
|
+
): void {
|
|
58
|
+
// Event listener implementation
|
|
59
|
+
throw new Error("Method not implemented.");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
removeEventListener<K extends keyof OffscreenCanvasEventMap>(
|
|
63
|
+
_type: K,
|
|
64
|
+
_listener: (this: OffscreenCanvas, ev: OffscreenCanvasEventMap[K]) => any,
|
|
65
|
+
_options?: boolean | EventListenerOptions,
|
|
66
|
+
): void {
|
|
67
|
+
// Remove event listener implementation
|
|
68
|
+
throw new Error("Method not implemented.");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
dispatchEvent(_event: Event): boolean {
|
|
72
|
+
// Event dispatch implementation
|
|
73
|
+
throw new Error("Method not implemented.");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
getImageData() {
|
|
77
|
+
const device = this.context.getDevice();
|
|
78
|
+
const texture = this.context.getTexture();
|
|
79
|
+
const commandEncoder = device.createCommandEncoder();
|
|
80
|
+
const bytesPerRow = this.width * 4;
|
|
81
|
+
const buffer = device.createBuffer({
|
|
82
|
+
size: bytesPerRow * this.height,
|
|
83
|
+
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
|
|
84
|
+
});
|
|
85
|
+
commandEncoder.copyTextureToBuffer(
|
|
86
|
+
{ texture: texture },
|
|
87
|
+
{ buffer: buffer, bytesPerRow },
|
|
88
|
+
[this.width, this.height],
|
|
89
|
+
);
|
|
90
|
+
device.queue.submit([commandEncoder.finish()]);
|
|
91
|
+
|
|
92
|
+
return buffer.mapAsync(GPUMapMode.READ).then(() => {
|
|
93
|
+
const arrayBuffer = buffer.getMappedRange();
|
|
94
|
+
const uint8Array = new Uint8Array(arrayBuffer);
|
|
95
|
+
const data = Array.from(uint8Array);
|
|
96
|
+
buffer.unmap();
|
|
97
|
+
return {
|
|
98
|
+
data,
|
|
99
|
+
width: this.width,
|
|
100
|
+
height: this.height,
|
|
101
|
+
format: navigator.gpu.getPreferredCanvasFormat(),
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
class GPUOffscreenCanvasContext implements GPUCanvasContext {
|
|
108
|
+
__brand = "GPUCanvasContext" as const;
|
|
109
|
+
|
|
110
|
+
private textureFormat: GPUTextureFormat;
|
|
111
|
+
private texture: GPUTexture | null = null;
|
|
112
|
+
private device: GPUDevice | null = null;
|
|
113
|
+
|
|
114
|
+
constructor(public readonly canvas: OffscreenCanvas) {
|
|
115
|
+
this.textureFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
getDevice() {
|
|
119
|
+
if (!this.device) {
|
|
120
|
+
throw new Error("Device is not configured.");
|
|
121
|
+
}
|
|
122
|
+
return this.device;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getTexture() {
|
|
126
|
+
if (!this.texture) {
|
|
127
|
+
throw new Error("Texture is not configured");
|
|
128
|
+
}
|
|
129
|
+
return this.texture;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
configure(config: GPUCanvasConfiguration) {
|
|
133
|
+
// Configure the canvas context with the device and format
|
|
134
|
+
this.device = config.device;
|
|
135
|
+
this.texture = config.device.createTexture({
|
|
136
|
+
size: [this.canvas.width, this.canvas.height],
|
|
137
|
+
format: this.textureFormat,
|
|
138
|
+
usage:
|
|
139
|
+
GPUTextureUsage.RENDER_ATTACHMENT |
|
|
140
|
+
GPUTextureUsage.COPY_SRC |
|
|
141
|
+
GPUTextureUsage.TEXTURE_BINDING,
|
|
142
|
+
});
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
unconfigure() {
|
|
147
|
+
// Unconfigure the canvas context
|
|
148
|
+
if (this.texture) {
|
|
149
|
+
this.texture.destroy();
|
|
150
|
+
}
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
getCurrentTexture(): GPUTexture {
|
|
155
|
+
if (!this.texture) {
|
|
156
|
+
throw new Error("Texture is not configured");
|
|
157
|
+
}
|
|
158
|
+
return this.texture;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -3,7 +3,7 @@ import { checkImage, client, encodeImage } from "./setup";
|
|
|
3
3
|
describe("External Textures", () => {
|
|
4
4
|
it("Simple (1)", async () => {
|
|
5
5
|
const result = await client.eval(
|
|
6
|
-
({ gpu, device, ctx, urls: { fTexture } }) => {
|
|
6
|
+
({ gpu, device, ctx, canvas, urls: { fTexture } }) => {
|
|
7
7
|
const module = device.createShaderModule({
|
|
8
8
|
label: "our hardcoded textured quad shaders",
|
|
9
9
|
code: /* wgsl */ `
|
|
@@ -131,7 +131,7 @@ describe("External Textures", () => {
|
|
|
131
131
|
device.queue.submit([commandBuffer]);
|
|
132
132
|
}
|
|
133
133
|
render();
|
|
134
|
-
return
|
|
134
|
+
return canvas.getImageData();
|
|
135
135
|
});
|
|
136
136
|
});
|
|
137
137
|
});
|
|
@@ -143,7 +143,7 @@ describe("External Textures", () => {
|
|
|
143
143
|
});
|
|
144
144
|
it("Simple (2)", async () => {
|
|
145
145
|
const result = await client.eval(
|
|
146
|
-
({ gpu, device, ctx, urls: { fTexture } }) => {
|
|
146
|
+
({ gpu, device, ctx, canvas, urls: { fTexture } }) => {
|
|
147
147
|
const module = device.createShaderModule({
|
|
148
148
|
label: "our hardcoded textured quad shaders",
|
|
149
149
|
code: /* wgsl */ `
|
|
@@ -271,7 +271,7 @@ describe("External Textures", () => {
|
|
|
271
271
|
device.queue.submit([commandBuffer]);
|
|
272
272
|
}
|
|
273
273
|
render();
|
|
274
|
-
return
|
|
274
|
+
return canvas.getImageData();
|
|
275
275
|
});
|
|
276
276
|
});
|
|
277
277
|
});
|
|
@@ -138,7 +138,13 @@ describe("Texture", () => {
|
|
|
138
138
|
});
|
|
139
139
|
it("Create texture and reads it", async () => {
|
|
140
140
|
const result = await client.eval(
|
|
141
|
-
({
|
|
141
|
+
({
|
|
142
|
+
device,
|
|
143
|
+
shaders: { triangleVertWGSL, redFragWGSL },
|
|
144
|
+
gpu,
|
|
145
|
+
ctx,
|
|
146
|
+
canvas,
|
|
147
|
+
}) => {
|
|
142
148
|
const pipeline = device.createRenderPipeline({
|
|
143
149
|
layout: "auto",
|
|
144
150
|
vertex: {
|
|
@@ -182,7 +188,7 @@ describe("Texture", () => {
|
|
|
182
188
|
passEncoder.end();
|
|
183
189
|
|
|
184
190
|
device.queue.submit([commandEncoder.finish()]);
|
|
185
|
-
return
|
|
191
|
+
return canvas.getImageData();
|
|
186
192
|
},
|
|
187
193
|
);
|
|
188
194
|
const image = encodeImage(result);
|
|
@@ -248,6 +248,7 @@ describe("A Buffer", () => {
|
|
|
248
248
|
translucentWGSL,
|
|
249
249
|
mat4,
|
|
250
250
|
vec3,
|
|
251
|
+
canvas,
|
|
251
252
|
}) => {
|
|
252
253
|
const presentationFormat = gpu.getPreferredCanvasFormat();
|
|
253
254
|
const settings = {
|
|
@@ -579,7 +580,7 @@ describe("A Buffer", () => {
|
|
|
579
580
|
}
|
|
580
581
|
|
|
581
582
|
const depthTexture = device.createTexture({
|
|
582
|
-
size: [ctx.width, ctx.height],
|
|
583
|
+
size: [ctx.canvas.width, ctx.canvas.height],
|
|
583
584
|
format: "depth24plus",
|
|
584
585
|
usage:
|
|
585
586
|
GPUTextureUsage.RENDER_ATTACHMENT |
|
|
@@ -605,12 +606,12 @@ describe("A Buffer", () => {
|
|
|
605
606
|
// We want to keep the linked-list buffer size under the maxStorageBufferBindingSize.
|
|
606
607
|
// Split the frame into enough slices to meet that constraint.
|
|
607
608
|
const bytesPerline =
|
|
608
|
-
ctx.width * averageLayersPerFragment * linkedListElementSize;
|
|
609
|
+
ctx.canvas.width * averageLayersPerFragment * linkedListElementSize;
|
|
609
610
|
const maxLinesSupported = Math.floor(
|
|
610
611
|
device.limits.maxStorageBufferBindingSize / bytesPerline,
|
|
611
612
|
);
|
|
612
|
-
const numSlices = Math.ceil(ctx.height / maxLinesSupported);
|
|
613
|
-
const sliceHeight = Math.ceil(ctx.height / numSlices);
|
|
613
|
+
const numSlices = Math.ceil(ctx.canvas.height / maxLinesSupported);
|
|
614
|
+
const sliceHeight = Math.ceil(ctx.canvas.height / numSlices);
|
|
614
615
|
const linkedListBufferSize = sliceHeight * bytesPerline;
|
|
615
616
|
|
|
616
617
|
const linkedListBuffer = device.createBuffer({
|
|
@@ -645,13 +646,17 @@ describe("A Buffer", () => {
|
|
|
645
646
|
// * numFragments : u32
|
|
646
647
|
// * data : array<u32>
|
|
647
648
|
const headsBuffer = device.createBuffer({
|
|
648
|
-
size:
|
|
649
|
+
size:
|
|
650
|
+
(1 + ctx.canvas.width * sliceHeight) *
|
|
651
|
+
Uint32Array.BYTES_PER_ELEMENT,
|
|
649
652
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
650
653
|
label: "headsBuffer",
|
|
651
654
|
});
|
|
652
655
|
|
|
653
656
|
const headsInitBuffer = device.createBuffer({
|
|
654
|
-
size:
|
|
657
|
+
size:
|
|
658
|
+
(1 + ctx.canvas.width * sliceHeight) *
|
|
659
|
+
Uint32Array.BYTES_PER_ELEMENT,
|
|
655
660
|
usage: GPUBufferUsage.COPY_SRC,
|
|
656
661
|
mappedAtCreation: true,
|
|
657
662
|
label: "headsInitBuffer",
|
|
@@ -745,7 +750,7 @@ describe("A Buffer", () => {
|
|
|
745
750
|
|
|
746
751
|
// Rotates the camera around the origin based on time.
|
|
747
752
|
function getCameraViewProjMatrix() {
|
|
748
|
-
const aspect = ctx.width / ctx.height;
|
|
753
|
+
const aspect = ctx.canvas.width / ctx.canvas.height;
|
|
749
754
|
|
|
750
755
|
const projectionMatrix = mat4.perspective(
|
|
751
756
|
(2 * Math.PI) / 5,
|
|
@@ -776,8 +781,8 @@ describe("A Buffer", () => {
|
|
|
776
781
|
|
|
777
782
|
new Float32Array(buffer).set(getCameraViewProjMatrix());
|
|
778
783
|
new Uint32Array(buffer, 16 * Float32Array.BYTES_PER_ELEMENT).set([
|
|
779
|
-
averageLayersPerFragment * ctx.width * sliceHeight,
|
|
780
|
-
ctx.width,
|
|
784
|
+
averageLayersPerFragment * ctx.canvas.width * sliceHeight,
|
|
785
|
+
ctx.canvas.width,
|
|
781
786
|
]);
|
|
782
787
|
|
|
783
788
|
device.queue.writeBuffer(uniformBuffer, 0, buffer);
|
|
@@ -810,9 +815,9 @@ describe("A Buffer", () => {
|
|
|
810
815
|
|
|
811
816
|
const scissorX = 0;
|
|
812
817
|
const scissorY = slice * sliceHeight;
|
|
813
|
-
const scissorWidth = ctx.width;
|
|
818
|
+
const scissorWidth = ctx.canvas.width;
|
|
814
819
|
const scissorHeight =
|
|
815
|
-
Math.min((slice + 1) * sliceHeight, ctx.height) -
|
|
820
|
+
Math.min((slice + 1) * sliceHeight, ctx.canvas.height) -
|
|
816
821
|
slice * sliceHeight;
|
|
817
822
|
|
|
818
823
|
// Draw the translucent objects
|
|
@@ -870,7 +875,7 @@ describe("A Buffer", () => {
|
|
|
870
875
|
|
|
871
876
|
doDraw();
|
|
872
877
|
|
|
873
|
-
return
|
|
878
|
+
return canvas.getImageData();
|
|
874
879
|
},
|
|
875
880
|
{
|
|
876
881
|
mesh: teapotMesh,
|
|
@@ -133,6 +133,7 @@ describe("Blur", () => {
|
|
|
133
133
|
assets: { di3D: imageBitmap },
|
|
134
134
|
fullscreenTexturedQuadWGSL,
|
|
135
135
|
blurWGSL,
|
|
136
|
+
canvas,
|
|
136
137
|
}) => {
|
|
137
138
|
const tileDim = 128;
|
|
138
139
|
const batch = [4, 4];
|
|
@@ -387,7 +388,7 @@ describe("Blur", () => {
|
|
|
387
388
|
device.queue.submit([commandEncoder.finish()]);
|
|
388
389
|
}
|
|
389
390
|
frame();
|
|
390
|
-
return
|
|
391
|
+
return canvas.getImageData();
|
|
391
392
|
},
|
|
392
393
|
{ blurWGSL: blur, fullscreenTexturedQuadWGSL: fullscreenTexturedQuad },
|
|
393
394
|
);
|
|
@@ -84,6 +84,7 @@ describe("Cube", () => {
|
|
|
84
84
|
vec3,
|
|
85
85
|
basicVertWGSL,
|
|
86
86
|
vertexPositionColorWGSL,
|
|
87
|
+
canvas,
|
|
87
88
|
}) => {
|
|
88
89
|
const cubeVertexSize = 4 * 10; // Byte size of one cube vertex.
|
|
89
90
|
const cubePositionOffset = 0;
|
|
@@ -156,7 +157,7 @@ describe("Cube", () => {
|
|
|
156
157
|
});
|
|
157
158
|
|
|
158
159
|
const depthTexture = device.createTexture({
|
|
159
|
-
size: [ctx.width, ctx.height],
|
|
160
|
+
size: [ctx.canvas.width, ctx.canvas.height],
|
|
160
161
|
format: "depth24plus",
|
|
161
162
|
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
162
163
|
});
|
|
@@ -196,7 +197,7 @@ describe("Cube", () => {
|
|
|
196
197
|
},
|
|
197
198
|
};
|
|
198
199
|
|
|
199
|
-
const aspect = ctx.width / ctx.height;
|
|
200
|
+
const aspect = ctx.canvas.width / ctx.canvas.height;
|
|
200
201
|
const projectionMatrix = mat4.perspective(
|
|
201
202
|
(2 * Math.PI) / 5,
|
|
202
203
|
aspect,
|
|
@@ -243,7 +244,7 @@ describe("Cube", () => {
|
|
|
243
244
|
passEncoder.draw(cubeVertexCount);
|
|
244
245
|
passEncoder.end();
|
|
245
246
|
device.queue.submit([commandEncoder.finish()]);
|
|
246
|
-
return
|
|
247
|
+
return canvas.getImageData();
|
|
247
248
|
},
|
|
248
249
|
{
|
|
249
250
|
basicVertWGSL: basicVert,
|
|
@@ -264,6 +265,7 @@ describe("Cube", () => {
|
|
|
264
265
|
vec3,
|
|
265
266
|
basicVertWGSL,
|
|
266
267
|
vertexPositionColorWGSL,
|
|
268
|
+
canvas,
|
|
267
269
|
}) => {
|
|
268
270
|
const cubeVertexSize = 4 * 10; // Byte size of one cube vertex.
|
|
269
271
|
const cubePositionOffset = 0;
|
|
@@ -334,7 +336,7 @@ describe("Cube", () => {
|
|
|
334
336
|
});
|
|
335
337
|
|
|
336
338
|
const depthTexture = device.createTexture({
|
|
337
|
-
size: [ctx.width, ctx.height],
|
|
339
|
+
size: [ctx.canvas.width, ctx.canvas.height],
|
|
338
340
|
format: "depth24plus",
|
|
339
341
|
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
340
342
|
});
|
|
@@ -395,7 +397,7 @@ describe("Cube", () => {
|
|
|
395
397
|
},
|
|
396
398
|
};
|
|
397
399
|
|
|
398
|
-
const aspect = ctx.width / ctx.height;
|
|
400
|
+
const aspect = ctx.canvas.width / ctx.canvas.height;
|
|
399
401
|
const projectionMatrix = mat4.perspective(
|
|
400
402
|
(2 * Math.PI) / 5,
|
|
401
403
|
aspect,
|
|
@@ -475,7 +477,7 @@ describe("Cube", () => {
|
|
|
475
477
|
passEncoder.end();
|
|
476
478
|
device.queue.submit([commandEncoder.finish()]);
|
|
477
479
|
|
|
478
|
-
return
|
|
480
|
+
return canvas.getImageData();
|
|
479
481
|
},
|
|
480
482
|
{
|
|
481
483
|
basicVertWGSL: basicVert,
|
|
@@ -496,6 +498,7 @@ describe("Cube", () => {
|
|
|
496
498
|
vec3,
|
|
497
499
|
basicVertWGSL,
|
|
498
500
|
sampleTextureMixColorWGSL,
|
|
501
|
+
canvas,
|
|
499
502
|
}) => {
|
|
500
503
|
const cubeVertexSize = 4 * 10; // Byte size of one cube vertex.
|
|
501
504
|
const cubePositionOffset = 0;
|
|
@@ -567,7 +570,7 @@ describe("Cube", () => {
|
|
|
567
570
|
});
|
|
568
571
|
|
|
569
572
|
const depthTexture = device.createTexture({
|
|
570
|
-
size: [ctx.width, ctx.height],
|
|
573
|
+
size: [ctx.canvas.width, ctx.canvas.height],
|
|
571
574
|
format: "depth24plus",
|
|
572
575
|
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
573
576
|
});
|
|
@@ -638,7 +641,7 @@ describe("Cube", () => {
|
|
|
638
641
|
},
|
|
639
642
|
};
|
|
640
643
|
|
|
641
|
-
const aspect = ctx.width / ctx.height;
|
|
644
|
+
const aspect = ctx.canvas.width / ctx.canvas.height;
|
|
642
645
|
const projectionMatrix = mat4.perspective(
|
|
643
646
|
(2 * Math.PI) / 5,
|
|
644
647
|
aspect,
|
|
@@ -686,7 +689,7 @@ describe("Cube", () => {
|
|
|
686
689
|
passEncoder.end();
|
|
687
690
|
device.queue.submit([commandEncoder.finish()]);
|
|
688
691
|
|
|
689
|
-
return
|
|
692
|
+
return canvas.getImageData();
|
|
690
693
|
},
|
|
691
694
|
{
|
|
692
695
|
basicVertWGSL: basicVert,
|
|
@@ -708,6 +711,7 @@ describe("Cube", () => {
|
|
|
708
711
|
vec3,
|
|
709
712
|
vertexPositionColorWGSL,
|
|
710
713
|
instancedVertWGSL,
|
|
714
|
+
canvas,
|
|
711
715
|
}) => {
|
|
712
716
|
const cubeVertexSize = 4 * 10; // Byte size of one cube vertex.
|
|
713
717
|
const cubePositionOffset = 0;
|
|
@@ -778,7 +782,7 @@ describe("Cube", () => {
|
|
|
778
782
|
});
|
|
779
783
|
|
|
780
784
|
const depthTexture = device.createTexture({
|
|
781
|
-
size: [ctx.width, ctx.height],
|
|
785
|
+
size: [ctx.canvas.width, ctx.canvas.height],
|
|
782
786
|
format: "depth24plus",
|
|
783
787
|
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
784
788
|
});
|
|
@@ -809,7 +813,7 @@ describe("Cube", () => {
|
|
|
809
813
|
],
|
|
810
814
|
});
|
|
811
815
|
|
|
812
|
-
const aspect = ctx.width / ctx.height;
|
|
816
|
+
const aspect = ctx.canvas.width / ctx.canvas.height;
|
|
813
817
|
const projectionMatrix = mat4.perspective(
|
|
814
818
|
(2 * Math.PI) / 5,
|
|
815
819
|
aspect,
|
|
@@ -912,7 +916,7 @@ describe("Cube", () => {
|
|
|
912
916
|
passEncoder.draw(cubeVertexCount, numInstances, 0, 0);
|
|
913
917
|
passEncoder.end();
|
|
914
918
|
device.queue.submit([commandEncoder.finish()]);
|
|
915
|
-
return
|
|
919
|
+
return canvas.getImageData();
|
|
916
920
|
},
|
|
917
921
|
{
|
|
918
922
|
vertexPositionColorWGSL: vertexPositionColor,
|