@flighthq/render-wgpu 0.2.0 → 0.2.1-next.410.a23f189
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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/wgpuDraw.d.ts +3 -2
- package/dist/wgpuDraw.d.ts.map +1 -1
- package/dist/wgpuDraw.js +88 -1
- package/dist/wgpuDraw.js.map +1 -1
- package/dist/wgpuFullscreenPass.js +1 -1
- package/dist/wgpuFullscreenPass.js.map +1 -1
- package/dist/wgpuMipmap.d.ts +4 -0
- package/dist/wgpuMipmap.d.ts.map +1 -0
- package/dist/wgpuMipmap.js +92 -0
- package/dist/wgpuMipmap.js.map +1 -0
- package/dist/wgpuRenderState.d.ts +3 -2
- package/dist/wgpuRenderState.d.ts.map +1 -1
- package/dist/wgpuRenderState.js +33 -0
- package/dist/wgpuRenderState.js.map +1 -1
- package/dist/wgpuRenderTarget.d.ts +4 -3
- package/dist/wgpuRenderTarget.d.ts.map +1 -1
- package/dist/wgpuRenderTarget.js +61 -11
- package/dist/wgpuRenderTarget.js.map +1 -1
- package/dist/wgpuShader.d.ts.map +1 -1
- package/dist/wgpuShader.js +6 -15
- package/dist/wgpuShader.js.map +1 -1
- package/dist/wgpuTextureUpload.d.ts +5 -0
- package/dist/wgpuTextureUpload.d.ts.map +1 -0
- package/dist/wgpuTextureUpload.js +25 -0
- package/dist/wgpuTextureUpload.js.map +1 -0
- package/package.json +6 -6
- package/src/wgpuDraw.test.ts +75 -0
- package/src/wgpuMipmap.test.ts +73 -0
- package/src/wgpuRenderState.test.ts +46 -0
- package/src/wgpuRenderTarget.test.ts +32 -14
- package/src/wgpuShader.test.ts +3 -6
- package/src/wgpuTextureUpload.test.ts +60 -0
|
@@ -3,12 +3,13 @@ import { createMatrix } from '@flighthq/geometry';
|
|
|
3
3
|
import { renderWgpuBackground, submitWgpuRenderPass } from './wgpuBackground';
|
|
4
4
|
import { getWgpuRenderStateRuntime } from './wgpuRenderState';
|
|
5
5
|
import {
|
|
6
|
-
|
|
6
|
+
beginWgpuRenderPass,
|
|
7
7
|
createWgpuRenderTarget,
|
|
8
8
|
destroyWgpuRenderTarget,
|
|
9
9
|
drawWgpuRenderTargetResult,
|
|
10
|
-
|
|
10
|
+
endWgpuRenderPass,
|
|
11
11
|
resizeWgpuRenderTarget,
|
|
12
|
+
setWgpuRenderTransform2D,
|
|
12
13
|
} from './wgpuRenderTarget';
|
|
13
14
|
import { createWgpuRenderStateForTest, installWgpuMock } from './wgpuTestHelper';
|
|
14
15
|
|
|
@@ -16,31 +17,28 @@ beforeAll(() => {
|
|
|
16
17
|
installWgpuMock();
|
|
17
18
|
});
|
|
18
19
|
|
|
19
|
-
describe('
|
|
20
|
+
describe('beginWgpuRenderPass', () => {
|
|
20
21
|
it('sets the render target viewport', async () => {
|
|
21
22
|
const state = await createWgpuRenderStateForTest();
|
|
22
23
|
renderWgpuBackground(state);
|
|
23
24
|
const target = createWgpuRenderTarget(state, 64, 64);
|
|
24
|
-
|
|
25
|
+
beginWgpuRenderPass(state, target);
|
|
25
26
|
expect(getWgpuRenderStateRuntime(state).renderTargetViewport?.width).toBe(64);
|
|
26
|
-
|
|
27
|
+
endWgpuRenderPass(state);
|
|
27
28
|
submitWgpuRenderPass(state);
|
|
28
29
|
});
|
|
29
|
-
});
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
it('switches the render target and restores it', async () => {
|
|
31
|
+
it('switches the render target and restores it on end', async () => {
|
|
33
32
|
const state = await createWgpuRenderStateForTest();
|
|
34
33
|
renderWgpuBackground(state);
|
|
35
34
|
|
|
36
35
|
const target = createWgpuRenderTarget(state, 128, 128);
|
|
37
|
-
|
|
38
|
-
beginWgpuRenderTarget(state, target, transform);
|
|
36
|
+
beginWgpuRenderPass(state, target);
|
|
39
37
|
|
|
40
38
|
const runtime = getWgpuRenderStateRuntime(state);
|
|
41
39
|
expect(runtime.renderTargetViewport?.width).toBe(128);
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
endWgpuRenderPass(state);
|
|
44
42
|
expect(runtime.renderTargetViewport).toBeNull();
|
|
45
43
|
|
|
46
44
|
submitWgpuRenderPass(state);
|
|
@@ -94,13 +92,13 @@ describe('drawWgpuRenderTargetResult', () => {
|
|
|
94
92
|
});
|
|
95
93
|
});
|
|
96
94
|
|
|
97
|
-
describe('
|
|
95
|
+
describe('endWgpuRenderPass', () => {
|
|
98
96
|
it('restores null renderTargetViewport', async () => {
|
|
99
97
|
const state = await createWgpuRenderStateForTest();
|
|
100
98
|
renderWgpuBackground(state);
|
|
101
99
|
const target = createWgpuRenderTarget(state, 32, 32);
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
beginWgpuRenderPass(state, target);
|
|
101
|
+
endWgpuRenderPass(state);
|
|
104
102
|
expect(getWgpuRenderStateRuntime(state).renderTargetViewport).toBeNull();
|
|
105
103
|
submitWgpuRenderPass(state);
|
|
106
104
|
});
|
|
@@ -118,3 +116,23 @@ describe('resizeWgpuRenderTarget', () => {
|
|
|
118
116
|
expect(target.bindGroup).not.toBe(previousBindGroup);
|
|
119
117
|
});
|
|
120
118
|
});
|
|
119
|
+
|
|
120
|
+
describe('setWgpuRenderTransform2D', () => {
|
|
121
|
+
it('installs a copy of the transform, restored by the enclosing pass', async () => {
|
|
122
|
+
const state = await createWgpuRenderStateForTest();
|
|
123
|
+
renderWgpuBackground(state);
|
|
124
|
+
const original = state.renderTransform2D;
|
|
125
|
+
const target = createWgpuRenderTarget(state, 32, 32);
|
|
126
|
+
const bake = createMatrix();
|
|
127
|
+
bake.tx = 42;
|
|
128
|
+
|
|
129
|
+
beginWgpuRenderPass(state, target);
|
|
130
|
+
setWgpuRenderTransform2D(state, bake);
|
|
131
|
+
expect(state.renderTransform2D?.tx).toBe(42);
|
|
132
|
+
expect(state.renderTransform2D).not.toBe(bake);
|
|
133
|
+
endWgpuRenderPass(state);
|
|
134
|
+
|
|
135
|
+
expect(state.renderTransform2D).toBe(original);
|
|
136
|
+
submitWgpuRenderPass(state);
|
|
137
|
+
});
|
|
138
|
+
});
|
package/src/wgpuShader.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BlendMode } from '@flighthq/types';
|
|
1
|
+
import { AdvancedBlendMode, BlendMode } from '@flighthq/types';
|
|
2
2
|
|
|
3
3
|
import { renderWgpuBackground } from './wgpuBackground';
|
|
4
4
|
import { getWgpuRenderStateRuntime } from './wgpuRenderState';
|
|
@@ -81,11 +81,8 @@ describe('getWgpuPipeline', () => {
|
|
|
81
81
|
operation: 'add',
|
|
82
82
|
});
|
|
83
83
|
expect(blendOf(BlendMode.Screen)).toEqual({ srcFactor: 'one', dstFactor: 'one-minus-src', operation: 'add' });
|
|
84
|
-
expect(blendOf(BlendMode.Erase)).toEqual({ srcFactor: 'zero', dstFactor: 'one-minus-src-alpha', operation: 'add' });
|
|
85
|
-
expect(blendOf(BlendMode.None)).toEqual({ srcFactor: 'one', dstFactor: 'zero', operation: 'add' });
|
|
86
84
|
expect(blendOf(BlendMode.Darken).operation).toBe('min');
|
|
87
85
|
expect(blendOf(BlendMode.Lighten).operation).toBe('max');
|
|
88
|
-
expect(blendOf(BlendMode.Subtract).operation).toBe('reverse-subtract');
|
|
89
86
|
});
|
|
90
87
|
|
|
91
88
|
it('falls back to normal blend for shader-composited modes', async () => {
|
|
@@ -95,12 +92,12 @@ describe('getWgpuPipeline', () => {
|
|
|
95
92
|
...(getWgpuPipeline(state, mode, 'normal') as unknown as { __descriptor: GPURenderPipelineDescriptor })
|
|
96
93
|
.__descriptor.fragment!.targets,
|
|
97
94
|
][0]!.blend!.color;
|
|
98
|
-
expect(blendOf(
|
|
95
|
+
expect(blendOf(AdvancedBlendMode.Overlay)).toEqual({
|
|
99
96
|
srcFactor: 'one',
|
|
100
97
|
dstFactor: 'one-minus-src-alpha',
|
|
101
98
|
operation: 'add',
|
|
102
99
|
});
|
|
103
|
-
expect(blendOf(
|
|
100
|
+
expect(blendOf(AdvancedBlendMode.HardLight)).toEqual({
|
|
104
101
|
srcFactor: 'one',
|
|
105
102
|
dstFactor: 'one-minus-src-alpha',
|
|
106
103
|
operation: 'add',
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { ImageResource } from '@flighthq/types';
|
|
2
|
+
|
|
3
|
+
import { uploadWgpuTextureData, uploadWgpuTextureElement, uploadWgpuTextureImageResource } from './wgpuTextureUpload';
|
|
4
|
+
|
|
5
|
+
// A device whose queue records the two upload calls so a test can assert which path ran and with what.
|
|
6
|
+
function makeDevice(): GPUDevice {
|
|
7
|
+
return {
|
|
8
|
+
queue: { writeTexture: vi.fn(), copyExternalImageToTexture: vi.fn() },
|
|
9
|
+
} as unknown as GPUDevice;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe('uploadWgpuTextureData', () => {
|
|
13
|
+
it('drives writeTexture with a tightly-packed rgba8 layout (bytesPerRow = width*4)', () => {
|
|
14
|
+
const device = makeDevice();
|
|
15
|
+
const texture = {} as GPUTexture;
|
|
16
|
+
const data = new Uint8ClampedArray(2 * 2 * 4);
|
|
17
|
+
uploadWgpuTextureData(device, texture, [0, 0, 3], 2, 2, data);
|
|
18
|
+
expect(device.queue.writeTexture).toHaveBeenCalledWith(
|
|
19
|
+
{ texture, origin: [0, 0, 3] },
|
|
20
|
+
data,
|
|
21
|
+
{ bytesPerRow: 8, rowsPerImage: 2 },
|
|
22
|
+
[2, 2, 1],
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('uploadWgpuTextureElement', () => {
|
|
28
|
+
it('drives copyExternalImageToTexture with the external source', () => {
|
|
29
|
+
const device = makeDevice();
|
|
30
|
+
const texture = {} as GPUTexture;
|
|
31
|
+
const source = {} as GPUCopyExternalImageSource;
|
|
32
|
+
uploadWgpuTextureElement(device, texture, [0, 0, 0], 4, 4, source);
|
|
33
|
+
expect(device.queue.copyExternalImageToTexture).toHaveBeenCalledWith(
|
|
34
|
+
{ source },
|
|
35
|
+
{ texture, origin: [0, 0, 0] },
|
|
36
|
+
[4, 4, 1],
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('uploadWgpuTextureImageResource', () => {
|
|
42
|
+
it('takes the element path when the resource carries a source', () => {
|
|
43
|
+
const device = makeDevice();
|
|
44
|
+
const texture = {} as GPUTexture;
|
|
45
|
+
const image = { source: {} as CanvasImageSource, data: null, width: 4, height: 4 } as ImageResource;
|
|
46
|
+
uploadWgpuTextureImageResource(device, texture, [0, 0, 0], image);
|
|
47
|
+
expect(device.queue.copyExternalImageToTexture).toHaveBeenCalledTimes(1);
|
|
48
|
+
expect(device.queue.writeTexture).not.toHaveBeenCalled();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('takes the raw-pixel path when the resource is data-only', () => {
|
|
52
|
+
const device = makeDevice();
|
|
53
|
+
const texture = {} as GPUTexture;
|
|
54
|
+
const data = new Uint8ClampedArray(4 * 4 * 4);
|
|
55
|
+
const image = { source: null, data, width: 4, height: 4 } as ImageResource;
|
|
56
|
+
uploadWgpuTextureImageResource(device, texture, [0, 0, 0], image);
|
|
57
|
+
expect(device.queue.writeTexture).toHaveBeenCalledTimes(1);
|
|
58
|
+
expect(device.queue.copyExternalImageToTexture).not.toHaveBeenCalled();
|
|
59
|
+
});
|
|
60
|
+
});
|