Skip to content

Commit 3d5aa39

Browse files
committed
add webgpu
1 parent 08aa591 commit 3d5aa39

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

Diff for: examples/_data.ts

+5
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,11 @@ export const sidebar = [
825825
id: "/examples/udp_connector",
826826
type: "example",
827827
},
828+
{
829+
label: "WebGPU",
830+
id: "/examples/webgpu",
831+
type: "example",
832+
},
828833
],
829834
},
830835
];

Diff for: examples/scripts/webgpu.ts

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/**
2+
* @title Render triangle to a window with WebGPU
3+
* @difficulty intermediate
4+
* @tags cli
5+
* @run --unstable-webgpu <url>
6+
* @resource {https://github.com/denoland/webgpu-examples} More WebGPU examples
7+
* @resource {https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API} WebGPU API documentation
8+
* @resource {https://webgpufundamentals.org/webgpu/lessons/webgpu-fundamentals.html} WebGPU fundamentals
9+
* @group Unstable APIs
10+
*/
11+
12+
// Import resources from https://github.com/denoland/webgpu-examples/blob/main/utils.ts
13+
// and Deno Standard Library's WebGPU module
14+
import { copyToBuffer, createPng, Dimensions } from "../utils.ts";
15+
import { createCapture } from "@jsr:std/[email protected]";
16+
17+
const dimensions: Dimensions = {
18+
width: 200,
19+
height: 200,
20+
};
21+
const adapter = await navigator.gpu.requestAdapter();
22+
const device = await adapter?.requestDevice();
23+
24+
if (!device) {
25+
console.error("no suitable adapter found");
26+
Deno.exit(0);
27+
}
28+
29+
// Define the vertex and fragment shaders that generate
30+
// the triangle using WebGPU Shading Language (WGSL)
31+
const shaderCode = `
32+
@vertex
33+
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
34+
let x = f32(i32(in_vertex_index) - 1);
35+
let y = f32(i32(in_vertex_index & 1u) * 2 - 1);
36+
return vec4<f32>(x, y, 0.0, 1.0);
37+
}
38+
39+
@fragment
40+
fn fs_main() -> @location(0) vec4<f32> {
41+
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
42+
}
43+
`;
44+
45+
// Creating a compiled shader module on GPU
46+
const shaderModule = device.createShaderModule({
47+
code: shaderCode,
48+
});
49+
50+
// Define pipelines for executing shader modules
51+
const pipelineLayout = device.createPipelineLayout({
52+
bindGroupLayouts: [],
53+
});
54+
const renderPipeline = device.createRenderPipeline({
55+
layout: pipelineLayout,
56+
vertex: {
57+
module: shaderModule,
58+
entryPoint: "vs_main",
59+
},
60+
fragment: {
61+
module: shaderModule,
62+
entryPoint: "fs_main",
63+
targets: [
64+
{
65+
format: "rgba8unorm-srgb",
66+
},
67+
],
68+
},
69+
});
70+
71+
// Create a texture and buffer to use as a capture
72+
const { texture, outputBuffer } = createCapture(
73+
device,
74+
dimensions.width,
75+
dimensions.height,
76+
);
77+
78+
// Create command encoder, which will encode commands
79+
// into command buffer, and render commands
80+
const encoder = device.createCommandEncoder();
81+
const renderPass = encoder.beginRenderPass({
82+
colorAttachments: [
83+
{
84+
view: texture.createView(),
85+
storeOp: "store",
86+
loadOp: "clear",
87+
clearValue: [0, 1, 0, 1],
88+
},
89+
],
90+
});
91+
renderPass.setPipeline(renderPipeline);
92+
renderPass.draw(3, 1);
93+
renderPass.end();
94+
95+
// Copy all to buffer
96+
copyToBuffer(encoder, texture, outputBuffer, dimensions);
97+
98+
// Submit buffer to have WebGPU execute commands
99+
device.queue.submit([encoder.finish()]);
100+
101+
// Create the png from the output buffer and defined dimensions
102+
await createPng(outputBuffer, dimensions);

0 commit comments

Comments
 (0)