@flighthq/render-wgpu 0.3.0-next.1452.011a16e → 0.3.0-next.1454.b17f8a5
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/dist/wgpuSurface.d.ts.map +1 -1
- package/dist/wgpuSurface.js +17 -0
- package/dist/wgpuSurface.js.map +1 -1
- package/package.json +11 -11
- package/src/wgpuSurface.test.ts +42 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuSurface.d.ts","sourceRoot":"","sources":["../src/wgpuSurface.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"wgpuSurface.d.ts","sourceRoot":"","sources":["../src/wgpuSurface.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAmBxE,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,UAAU,GAAG,IAAI,CAmBlG;AAWD,wBAAsB,+BAA+B,CACnD,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,EAChC,SAAS,SAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAMD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,IAAI,CAE7E;AAKD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAsCzG"}
|
package/dist/wgpuSurface.js
CHANGED
|
@@ -6,6 +6,11 @@ import { getWgpuRenderStateRuntime } from './wgpuRenderState';
|
|
|
6
6
|
// renderWgpuBackground); (2) GPU work queued in a later task than the frame is dropped on these
|
|
7
7
|
// adapters, so submitWgpuRenderPass copies the capture texture into the retained capture buffer in the
|
|
8
8
|
// same frame (encodeWgpuFrameCapture), and createBitmapFromWgpuRenderState only maps that buffer.
|
|
9
|
+
//
|
|
10
|
+
// One buffer serves both sides, so they take turns: the writer skips its copy while the reader holds a
|
|
11
|
+
// map (or has one in flight), and resumes on the next frame. Without that turn-taking a continuously
|
|
12
|
+
// animating scene re-enqueues a copy every frame into the buffer a readback is waiting on — which the
|
|
13
|
+
// queue may not touch while it is mapped, and which pushes the pending map behind ever more GPU work.
|
|
9
14
|
// Returns the offscreen texture the frame should render into when capture is enabled, creating/resizing
|
|
10
15
|
// it to the canvas on demand, or null when capture is off (the caller then renders to the swapchain).
|
|
11
16
|
// Internal: called by renderWgpuBackground to redirect the frame so its pixels stay readable.
|
|
@@ -89,6 +94,18 @@ export function encodeWgpuFrameCapture(state, encoder) {
|
|
|
89
94
|
const texture = runtime.frameCaptureTexture;
|
|
90
95
|
if (!runtime.frameCaptureEnabled || texture === null || texture === undefined)
|
|
91
96
|
return;
|
|
97
|
+
// The reader owns the buffer while it holds a map. One retained buffer serves both sides, and the
|
|
98
|
+
// queue may not touch a buffer that is mapped or has a map in flight — so a frame encoded during a
|
|
99
|
+
// readback both invalidates the copy and stacks more GPU work in front of the map it is waiting on.
|
|
100
|
+
// Skipping the frame is the handshake: the reader is already taking a snapshot, and the next frame
|
|
101
|
+
// resumes copying once it lets go.
|
|
102
|
+
//
|
|
103
|
+
// Deliberately written as "is it busy" rather than "is it not unmapped": an implementation without
|
|
104
|
+
// `mapState` reports undefined, and the inverted test would then skip every copy for the whole run
|
|
105
|
+
// and capture nothing. Unknown state falls through to the copy, which is the pre-existing behaviour.
|
|
106
|
+
const mapState = runtime.frameCaptureBuffer?.mapState;
|
|
107
|
+
if (mapState === 'pending' || mapState === 'mapped')
|
|
108
|
+
return;
|
|
92
109
|
const width = texture.width;
|
|
93
110
|
const height = texture.height;
|
|
94
111
|
// Wgpu requires copyTextureToBuffer rows to be 256-byte aligned; the buffer is padded per row.
|
package/dist/wgpuSurface.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuSurface.js","sourceRoot":"","sources":["../src/wgpuSurface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,gGAAgG;AAChG,sGAAsG;AACtG,sGAAsG;AACtG,gGAAgG;AAChG,uGAAuG;AACvG,kGAAkG;
|
|
1
|
+
{"version":3,"file":"wgpuSurface.js","sourceRoot":"","sources":["../src/wgpuSurface.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/render-wgpu",
|
|
3
|
-
"version": "0.3.0-next.
|
|
3
|
+
"version": "0.3.0-next.1454.b17f8a5",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/flighthq/flight.git",
|
|
@@ -36,16 +36,16 @@
|
|
|
36
36
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@flighthq/color": "0.3.0-next.
|
|
40
|
-
"@flighthq/entity": "0.3.0-next.
|
|
41
|
-
"@flighthq/scene2d": "0.3.0-next.
|
|
42
|
-
"@flighthq/geometry": "0.3.0-next.
|
|
43
|
-
"@flighthq/log": "0.3.0-next.
|
|
44
|
-
"@flighthq/render": "0.3.0-next.
|
|
45
|
-
"@flighthq/signals": "0.3.0-next.
|
|
46
|
-
"@flighthq/bitmap": "0.3.0-next.
|
|
47
|
-
"@flighthq/texture": "0.3.0-next.
|
|
48
|
-
"@flighthq/types": "0.3.0-next.
|
|
39
|
+
"@flighthq/color": "0.3.0-next.1454.b17f8a5",
|
|
40
|
+
"@flighthq/entity": "0.3.0-next.1454.b17f8a5",
|
|
41
|
+
"@flighthq/scene2d": "0.3.0-next.1454.b17f8a5",
|
|
42
|
+
"@flighthq/geometry": "0.3.0-next.1454.b17f8a5",
|
|
43
|
+
"@flighthq/log": "0.3.0-next.1454.b17f8a5",
|
|
44
|
+
"@flighthq/render": "0.3.0-next.1454.b17f8a5",
|
|
45
|
+
"@flighthq/signals": "0.3.0-next.1454.b17f8a5",
|
|
46
|
+
"@flighthq/bitmap": "0.3.0-next.1454.b17f8a5",
|
|
47
|
+
"@flighthq/texture": "0.3.0-next.1454.b17f8a5",
|
|
48
|
+
"@flighthq/types": "0.3.0-next.1454.b17f8a5"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@webgpu/types": "*",
|
package/src/wgpuSurface.test.ts
CHANGED
|
@@ -96,4 +96,46 @@ describe('encodeWgpuFrameCapture', () => {
|
|
|
96
96
|
encodeWgpuFrameCapture(state, encoder);
|
|
97
97
|
expect(copied).toBe(false);
|
|
98
98
|
});
|
|
99
|
+
|
|
100
|
+
it('skips the copy while a readback holds the buffer, and resumes once it lets go', async () => {
|
|
101
|
+
// The writer/reader handshake over the single retained buffer: an animating scene must not keep
|
|
102
|
+
// enqueueing copies into a buffer a readback has mapped or is waiting to map.
|
|
103
|
+
const state = await createWgpuRenderStateForTest();
|
|
104
|
+
enableWgpuFrameCapture(state);
|
|
105
|
+
acquireWgpuFrameCaptureTexture(state);
|
|
106
|
+
const runtime = getWgpuRenderStateRuntime(state);
|
|
107
|
+
let mapState: GPUBufferMapState = 'unmapped';
|
|
108
|
+
installCaptureBuffer(state, () => Promise.resolve());
|
|
109
|
+
Object.defineProperty(runtime.frameCaptureBuffer, 'mapState', { get: () => mapState });
|
|
110
|
+
|
|
111
|
+
let copies = 0;
|
|
112
|
+
const encoder = { copyTextureToBuffer: () => copies++ } as unknown as GPUCommandEncoder;
|
|
113
|
+
|
|
114
|
+
mapState = 'pending';
|
|
115
|
+
encodeWgpuFrameCapture(state, encoder);
|
|
116
|
+
mapState = 'mapped';
|
|
117
|
+
encodeWgpuFrameCapture(state, encoder);
|
|
118
|
+
expect(copies).toBe(0);
|
|
119
|
+
|
|
120
|
+
mapState = 'unmapped';
|
|
121
|
+
encodeWgpuFrameCapture(state, encoder);
|
|
122
|
+
expect(copies).toBe(1);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('still copies when the implementation reports no map state at all', async () => {
|
|
126
|
+
// Fails safe in the direction that keeps capturing: an undefined mapState must not read as "busy"
|
|
127
|
+
// and silence every copy for the rest of the run.
|
|
128
|
+
const state = await createWgpuRenderStateForTest();
|
|
129
|
+
enableWgpuFrameCapture(state);
|
|
130
|
+
acquireWgpuFrameCaptureTexture(state);
|
|
131
|
+
installCaptureBuffer(state, () => Promise.resolve());
|
|
132
|
+
Object.defineProperty(getWgpuRenderStateRuntime(state).frameCaptureBuffer, 'mapState', {
|
|
133
|
+
get: () => undefined,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
let copies = 0;
|
|
137
|
+
encodeWgpuFrameCapture(state, { copyTextureToBuffer: () => copies++ } as unknown as GPUCommandEncoder);
|
|
138
|
+
|
|
139
|
+
expect(copies).toBe(1);
|
|
140
|
+
});
|
|
99
141
|
});
|