Skip to content

Commit 4227e5c

Browse files
committed
feat: webgpu wrapper
1 parent 75cc6d3 commit 4227e5c

File tree

13 files changed

+345
-175
lines changed

13 files changed

+345
-175
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,3 @@ jobs:
2020

2121
- name: Deno Fmt
2222
run: deno fmt --check
23-
24-
- name: Deno Lint
25-
run: deno lint

README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
createWindow,
1818
getProcAddress,
1919
mainloop,
20-
} from "https://deno.land/x/[email protected]/mod.ts";
20+
} from "jsr:@gfx/dwm";
2121
import * as gl from "https://deno.land/x/[email protected]/api/gles23.2.ts";
2222

2323
const window = createWindow({
@@ -51,7 +51,7 @@ await mainloop(frame);
5151
import {
5252
mainloop,
5353
WindowCanvas,
54-
} from "https://deno.land/x/dwm@0.3.4/ext/canvas.ts";
54+
} from "jsr:@gfx/dwm/ext/canvas";
5555

5656
const canvas = new WindowCanvas({
5757
title: "Skia Canvas",
@@ -80,14 +80,12 @@ See [examples](./examples) for more examples!
8080

8181
For drawing, you can use:
8282

83+
- [WebGPU](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) (Use `ext/webgpu` for an easy to use wrapper)
8384
- [Deno Gluten](https://github.com/deno-windowing/gluten)
8485
- [Skia Canvas](https://github.com/DjDeveloperr/skia_canvas) (Use
85-
`ext/canvas.ts` for an easy to use wrapper)
86+
`ext/canvas` for an easy to use wrapper)
8687
- [Deno Vulkan](https://github.com/deno-windowing/vulkan)
8788

88-
To package your application you can use:
89-
90-
- [wpack](https://github.com/deno-windowing/wpack)
9189

9290
Since this module depends on unstable FFI API, you need to pass `--unstable`
9391
along with `--allow-ffi`, `--allow-write` and `--allow-env`.

deno.jsonc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
22
"name": "@gfx/dwm",
33
"license": "Apache-2.0",
4-
"version": "0.3.8",
4+
"version": "0.3.9",
55
"exports": {
66
".": "./mod.ts",
7-
"./ext/canvas": "./ext/canvas.ts"
7+
"./ext/canvas": "./ext/canvas.ts",
8+
"./ext/webgpu": "./ext/webgpu.ts"
89
},
910
"tasks": {
1011
"example:opengl": "deno run -A --unstable examples/opengl.ts",

examples/webgpu-cube-floating.ts

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// ported from https://github.com/webgpu/webgpu-samples/blob/main/src/sample/rotatingCube/main.ts
22
import { mat4, vec3 } from "npm:wgpu-matrix";
3-
import { createWindow, mainloop } from "../mod.ts";
4-
5-
const adapter = await navigator.gpu.requestAdapter();
6-
const device = await adapter!.requestDevice();
3+
import { createWindowGPU, mainloop } from "../ext/webgpu.ts";
74

85
const cubeVertexSize = 4 * 10;
96
const cubePositionOffset = 0;
@@ -56,7 +53,7 @@ export const cubeVertexArray = new Float32Array([
5653
-1, 1, -1, 1, 0, 1, 0, 1, 1, 0,
5754
]);
5855

59-
const window = createWindow({
56+
const window = await createWindowGPU({
6057
title: "Deno Window Manager",
6158
width: 512,
6259
height: 512,
@@ -66,29 +63,25 @@ const window = createWindow({
6663
floating: true,
6764
});
6865

69-
const { width, height } = window.framebufferSize;
70-
71-
const surface = window.windowSurface();
72-
73-
const context = surface.getContext("webgpu");
66+
const context = window.getContext("webgpu");
7467

7568
context.configure({
76-
device,
69+
device: window.device,
7770
format: "bgra8unorm",
7871
});
7972

80-
const verticesBuffer = device.createBuffer({
73+
const verticesBuffer = window.device.createBuffer({
8174
size: cubeVertexArray.byteLength,
8275
usage: GPUBufferUsage.VERTEX,
8376
mappedAtCreation: true,
8477
});
8578
new Float32Array(verticesBuffer.getMappedRange()).set(cubeVertexArray);
8679
verticesBuffer.unmap();
8780

88-
const pipeline = device.createRenderPipeline({
81+
const pipeline = window.device.createRenderPipeline({
8982
layout: "auto",
9083
vertex: {
91-
module: device.createShaderModule({
84+
module: window.device.createShaderModule({
9285
code: `
9386
struct Uniforms {
9487
modelViewProjectionMatrix : mat4x4<f32>,
@@ -136,7 +129,7 @@ const pipeline = device.createRenderPipeline({
136129
],
137130
},
138131
fragment: {
139-
module: device.createShaderModule({
132+
module: window.device.createShaderModule({
140133
code: `@fragment
141134
fn main(
142135
@location(0) fragUV: vec2<f32>,
@@ -170,19 +163,22 @@ const pipeline = device.createRenderPipeline({
170163
},
171164
});
172165

173-
const depthTexture = device.createTexture({
174-
size: [width, height],
166+
const depthTexture = window.device.createTexture({
167+
size: [
168+
window.window.framebufferSize.width,
169+
window.window.framebufferSize.height,
170+
],
175171
format: "depth24plus",
176172
usage: GPUTextureUsage.RENDER_ATTACHMENT,
177173
});
178174

179175
const uniformBufferSize = 4 * 16; // 4x4 matrix
180-
const uniformBuffer = device.createBuffer({
176+
const uniformBuffer = window.device.createBuffer({
181177
size: uniformBufferSize,
182178
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
183179
});
184180

185-
const uniformBindGroup = device.createBindGroup({
181+
const uniformBindGroup = window.device.createBindGroup({
186182
layout: pipeline.getBindGroupLayout(0),
187183
entries: [
188184
{
@@ -213,7 +209,8 @@ const renderPassDescriptor: GPURenderPassDescriptor = {
213209
depthStoreOp: "store",
214210
},
215211
};
216-
const aspect = width / height;
212+
const aspect = window.window.framebufferSize.width /
213+
window.window.framebufferSize.height;
217214
const projectionMatrix = mat4.perspective(
218215
(2 * Math.PI) / 5,
219216
aspect,
@@ -240,7 +237,7 @@ function getTransformationMatrix() {
240237

241238
mainloop(() => {
242239
const transformationMatrix = getTransformationMatrix();
243-
device.queue.writeBuffer(
240+
window.device.queue.writeBuffer(
244241
uniformBuffer,
245242
0,
246243
transformationMatrix.buffer,
@@ -251,13 +248,13 @@ mainloop(() => {
251248
.getCurrentTexture()
252249
.createView();
253250

254-
const commandEncoder = device.createCommandEncoder();
251+
const commandEncoder = window.device.createCommandEncoder();
255252
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
256253
passEncoder.setPipeline(pipeline);
257254
passEncoder.setBindGroup(0, uniformBindGroup);
258255
passEncoder.setVertexBuffer(0, verticesBuffer);
259256
passEncoder.draw(cubeVertexCount);
260257
passEncoder.end();
261-
device.queue.submit([commandEncoder.finish()]);
262-
surface.present();
258+
window.device.queue.submit([commandEncoder.finish()]);
259+
window.surface.present();
263260
}, false);

examples/webgpu-cube.ts

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
// ported from https://github.com/webgpu/webgpu-samples/blob/main/src/sample/rotatingCube/main.ts
22
import { mat4, vec3 } from "npm:wgpu-matrix";
3-
import { createWindow, mainloop } from "../mod.ts";
3+
import { createWindowGPU, mainloop } from "../ext/webgpu.ts";
44

5-
const adapter = await navigator.gpu.requestAdapter();
6-
const device = await adapter!.requestDevice();
5+
const window = await createWindowGPU({
6+
title: "Deno Window Manager",
7+
width: 512,
8+
height: 512,
9+
resizable: true,
10+
});
11+
12+
const context = window.getContext("webgpu");
13+
14+
context.configure({
15+
device: window.device,
16+
format: "bgra8unorm",
17+
});
718

819
const cubeVertexSize = 4 * 10;
920
const cubePositionOffset = 0;
@@ -56,36 +67,18 @@ export const cubeVertexArray = new Float32Array([
5667
-1, 1, -1, 1, 0, 1, 0, 1, 1, 0,
5768
]);
5869

59-
const window = createWindow({
60-
title: "Deno Window Manager",
61-
width: 512,
62-
height: 512,
63-
resizable: true,
64-
});
65-
66-
const { width, height } = window.framebufferSize;
67-
68-
const surface = window.windowSurface();
69-
70-
const context = surface.getContext("webgpu");
71-
72-
context.configure({
73-
device,
74-
format: "bgra8unorm",
75-
});
76-
77-
const verticesBuffer = device.createBuffer({
70+
const verticesBuffer = window.device.createBuffer({
7871
size: cubeVertexArray.byteLength,
7972
usage: GPUBufferUsage.VERTEX,
8073
mappedAtCreation: true,
8174
});
8275
new Float32Array(verticesBuffer.getMappedRange()).set(cubeVertexArray);
8376
verticesBuffer.unmap();
8477

85-
const pipeline = device.createRenderPipeline({
78+
const pipeline = window.device.createRenderPipeline({
8679
layout: "auto",
8780
vertex: {
88-
module: device.createShaderModule({
81+
module: window.device.createShaderModule({
8982
code: `
9083
struct Uniforms {
9184
modelViewProjectionMatrix : mat4x4<f32>,
@@ -133,7 +126,7 @@ const pipeline = device.createRenderPipeline({
133126
],
134127
},
135128
fragment: {
136-
module: device.createShaderModule({
129+
module: window.device.createShaderModule({
137130
code: `@fragment
138131
fn main(
139132
@location(0) fragUV: vec2<f32>,
@@ -167,19 +160,19 @@ const pipeline = device.createRenderPipeline({
167160
},
168161
});
169162

170-
const depthTexture = device.createTexture({
171-
size: [width, height],
163+
const depthTexture = window.device.createTexture({
164+
size: [window.window.size.width, window.window.size.height],
172165
format: "depth24plus",
173166
usage: GPUTextureUsage.RENDER_ATTACHMENT,
174167
});
175168

176169
const uniformBufferSize = 4 * 16; // 4x4 matrix
177-
const uniformBuffer = device.createBuffer({
170+
const uniformBuffer = window.device.createBuffer({
178171
size: uniformBufferSize,
179172
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
180173
});
181174

182-
const uniformBindGroup = device.createBindGroup({
175+
const uniformBindGroup = window.device.createBindGroup({
183176
layout: pipeline.getBindGroupLayout(0),
184177
entries: [
185178
{
@@ -210,7 +203,7 @@ const renderPassDescriptor: GPURenderPassDescriptor = {
210203
depthStoreOp: "store",
211204
},
212205
};
213-
const aspect = width / height;
206+
const aspect = window.window.size.width / window.window.size.height;
214207
const projectionMatrix = mat4.perspective(
215208
(2 * Math.PI) / 5,
216209
aspect,
@@ -237,7 +230,7 @@ function getTransformationMatrix() {
237230

238231
mainloop(() => {
239232
const transformationMatrix = getTransformationMatrix();
240-
device.queue.writeBuffer(
233+
window.device.queue.writeBuffer(
241234
uniformBuffer,
242235
0,
243236
transformationMatrix.buffer,
@@ -248,13 +241,13 @@ mainloop(() => {
248241
.getCurrentTexture()
249242
.createView();
250243

251-
const commandEncoder = device.createCommandEncoder();
244+
const commandEncoder = window.device.createCommandEncoder();
252245
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
253246
passEncoder.setPipeline(pipeline);
254247
passEncoder.setBindGroup(0, uniformBindGroup);
255248
passEncoder.setVertexBuffer(0, verticesBuffer);
256249
passEncoder.draw(cubeVertexCount);
257250
passEncoder.end();
258-
device.queue.submit([commandEncoder.finish()]);
259-
surface.present();
251+
window.device.queue.submit([commandEncoder.finish()]);
252+
window.surface.present();
260253
}, false);

0 commit comments

Comments
 (0)