-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: bring back WebGPU #20812
Merged
Merged
feat: bring back WebGPU #20812
Changes from 1 commit
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
bc3fbf5
bring back webgpu infrastructure
crowlKats 1b1e475
pull in webgpu
crowlKats 6d56745
use git dep
crowlKats b54794f
fix
crowlKats b7019a6
feat(streams): ReadableStream.read min option
crowlKats d7e4d02
fix converters and asserts
crowlKats d88baf4
add CoreGraphics
crowlKats e7e024b
Update ext/webgpu/01_webgpu.js
crowlKats a5dc8f2
Update ext/webgpu/01_webgpu.js
crowlKats 15c8e6a
Update ext/webgpu/01_webgpu.js
crowlKats f3d8934
Update ext/webgpu/01_webgpu.js
crowlKats c0ac159
Update ext/webgpu/01_webgpu.js
crowlKats 59e5b5d
Update ext/webgpu/01_webgpu.js
crowlKats 786de65
Update ext/webgpu/01_webgpu.js
crowlKats b142f39
Apply suggestions from code review
crowlKats c47e3ff
Update ext/webgpu/01_webgpu.js
crowlKats d317f0c
address comments
crowlKats 91532f1
Merge branch 'main' into webgpu
crowlKats ddd6879
some fixes
crowlKats 8ea8ddc
format and fix
crowlKats 44c0674
lazy load
crowlKats d4e85d3
cleanup
crowlKats e64d31f
Merge branch 'main' into webgpu
crowlKats 59c7397
update primordials import
crowlKats f1fbfd9
remove duplicate brand assert
crowlKats 3f15523
fmt
crowlKats d41b6c5
ci
crowlKats 7825789
safety comments
crowlKats 41e3929
fix
crowlKats 554df0c
fmt
crowlKats de9bc5f
primordials
crowlKats 36846d2
fix config.toml
crowlKats 7d68d7c
fix primordials
crowlKats 7665e8e
Merge branch 'main' into webgpu
crowlKats bb0bd0e
update wgpu
crowlKats 569fd1b
fix the build
bartlomieju 0602fc6
pin reqwest
crowlKats ab295e5
fix
crowlKats 68465cb
fix unstable flag order
crowlKats 14f0375
fix test
crowlKats bbdba51
update macos_shared_libraries to check for weak linking
crowlKats 76d5234
Merge branch 'main' into webgpu
crowlKats 99fa18b
fix unstable handling
crowlKats 3800f11
fmt
crowlKats 6c91999
fix test
crowlKats dcd94a2
Merge branch 'main' into webgpu
crowlKats 1efcd93
adress comments
crowlKats 42aff1b
fmt
crowlKats File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
@group(0) | ||
@binding(0) | ||
var<storage, read_write> v_indices: array<u32>; // this is used as both input and output for convenience | ||
|
||
// The Collatz Conjecture states that for any integer n: | ||
// If n is even, n = n/2 | ||
// If n is odd, n = 3n+1 | ||
// And repeat this process for each new n, you will always eventually reach 1. | ||
// Though the conjecture has not been proven, no counterexample has ever been found. | ||
// This function returns how many times this recurrence needs to be applied to reach 1. | ||
fn collatz_iterations(n_base: u32) -> u32{ | ||
var n: u32 = n_base; | ||
var i: u32 = 0u; | ||
loop { | ||
if (n <= 1u) { | ||
break; | ||
} | ||
if (n % 2u == 0u) { | ||
n = n / 2u; | ||
} | ||
else { | ||
// Overflow? (i.e. 3*n + 1 > 0xffffffffu?) | ||
if (n >= 1431655765u) { // 0x55555555u | ||
return 4294967295u; // 0xffffffffu | ||
} | ||
|
||
n = 3u * n + 1u; | ||
} | ||
i = i + 1u; | ||
} | ||
return i; | ||
} | ||
|
||
@compute | ||
@workgroup_size(1) | ||
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) { | ||
v_indices[global_id.x] = collatz_iterations(v_indices[global_id.x]); | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
@vertex | ||
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> { | ||
let x = f32(i32(in_vertex_index) - 1); | ||
let y = f32(i32(in_vertex_index & 1u) * 2 - 1); | ||
return vec4<f32>(x, y, 0.0, 1.0); | ||
} | ||
|
||
@fragment | ||
fn fs_main() -> @location(0) vec4<f32> { | ||
return vec4<f32>(1.0, 0.0, 0.0, 1.0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,242 @@ | ||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. | ||
|
||
import { assert, assertEquals } from "./test_util.ts"; | ||
|
||
let isCI: boolean; | ||
try { | ||
isCI = (Deno.env.get("CI")?.length ?? 0) > 0; | ||
} catch { | ||
isCI = true; | ||
} | ||
|
||
// Skip these tests on linux CI, because the vulkan emulator is not good enough | ||
// yet, and skip on macOS CI because these do not have virtual GPUs. | ||
const isLinuxOrMacCI = | ||
(Deno.build.os === "linux" || Deno.build.os === "darwin") && isCI; | ||
// Skip these tests in WSL because it doesn't have good GPU support. | ||
const isWsl = await checkIsWsl(); | ||
|
||
Deno.test({ | ||
permissions: { read: true, env: true }, | ||
ignore: isWsl || isLinuxOrMacCI, | ||
bartlomieju marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, async function webgpuComputePass() { | ||
const adapter = await navigator.gpu.requestAdapter(); | ||
assert(adapter); | ||
|
||
const numbers = [1, 4, 3, 295]; | ||
|
||
const device = await adapter.requestDevice(); | ||
assert(device); | ||
|
||
const shaderCode = await Deno.readTextFile( | ||
"cli/tests/testdata/webgpu/computepass_shader.wgsl", | ||
); | ||
|
||
const shaderModule = device.createShaderModule({ | ||
code: shaderCode, | ||
}); | ||
|
||
const size = new Uint32Array(numbers).byteLength; | ||
|
||
const stagingBuffer = device.createBuffer({ | ||
size: size, | ||
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST, | ||
}); | ||
|
||
const storageBuffer = device.createBuffer({ | ||
label: "Storage Buffer", | ||
size: size, | ||
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | | ||
GPUBufferUsage.COPY_SRC, | ||
mappedAtCreation: true, | ||
}); | ||
|
||
const buf = new Uint32Array(storageBuffer.getMappedRange()); | ||
|
||
buf.set(numbers); | ||
|
||
storageBuffer.unmap(); | ||
|
||
const computePipeline = device.createComputePipeline({ | ||
layout: "auto", | ||
compute: { | ||
module: shaderModule, | ||
entryPoint: "main", | ||
}, | ||
}); | ||
const bindGroupLayout = computePipeline.getBindGroupLayout(0); | ||
|
||
const bindGroup = device.createBindGroup({ | ||
layout: bindGroupLayout, | ||
entries: [ | ||
{ | ||
binding: 0, | ||
resource: { | ||
buffer: storageBuffer, | ||
}, | ||
}, | ||
], | ||
}); | ||
|
||
const encoder = device.createCommandEncoder(); | ||
|
||
const computePass = encoder.beginComputePass(); | ||
computePass.setPipeline(computePipeline); | ||
computePass.setBindGroup(0, bindGroup); | ||
computePass.insertDebugMarker("compute collatz iterations"); | ||
computePass.dispatchWorkgroups(numbers.length); | ||
computePass.end(); | ||
|
||
encoder.copyBufferToBuffer(storageBuffer, 0, stagingBuffer, 0, size); | ||
|
||
device.queue.submit([encoder.finish()]); | ||
|
||
await stagingBuffer.mapAsync(1); | ||
|
||
const data = stagingBuffer.getMappedRange(); | ||
|
||
assertEquals(new Uint32Array(data), new Uint32Array([0, 2, 7, 55])); | ||
|
||
stagingBuffer.unmap(); | ||
|
||
device.destroy(); | ||
|
||
// TODO(lucacasonato): webgpu spec should add a explicit destroy method for | ||
// adapters. | ||
const resources = Object.keys(Deno.resources()); | ||
Deno.close(Number(resources[resources.length - 1])); | ||
}); | ||
|
||
Deno.test({ | ||
permissions: { read: true, env: true }, | ||
ignore: isWsl || isLinuxOrMacCI, | ||
}, async function webgpuHelloTriangle() { | ||
const adapter = await navigator.gpu.requestAdapter(); | ||
assert(adapter); | ||
|
||
const device = await adapter.requestDevice(); | ||
assert(device); | ||
|
||
const shaderCode = await Deno.readTextFile( | ||
"cli/tests/testdata/webgpu/hellotriangle_shader.wgsl", | ||
); | ||
|
||
const shaderModule = device.createShaderModule({ | ||
code: shaderCode, | ||
}); | ||
|
||
const pipelineLayout = device.createPipelineLayout({ | ||
bindGroupLayouts: [], | ||
}); | ||
|
||
const renderPipeline = device.createRenderPipeline({ | ||
layout: pipelineLayout, | ||
vertex: { | ||
module: shaderModule, | ||
entryPoint: "vs_main", | ||
}, | ||
fragment: { | ||
module: shaderModule, | ||
entryPoint: "fs_main", | ||
targets: [ | ||
{ | ||
format: "rgba8unorm-srgb", | ||
}, | ||
], | ||
}, | ||
}); | ||
|
||
const dimensions = { | ||
width: 200, | ||
height: 200, | ||
}; | ||
const unpaddedBytesPerRow = dimensions.width * 4; | ||
const align = 256; | ||
const paddedBytesPerRowPadding = (align - unpaddedBytesPerRow % align) % | ||
align; | ||
const paddedBytesPerRow = unpaddedBytesPerRow + paddedBytesPerRowPadding; | ||
|
||
const outputBuffer = device.createBuffer({ | ||
label: "Capture", | ||
size: paddedBytesPerRow * dimensions.height, | ||
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST, | ||
}); | ||
const texture = device.createTexture({ | ||
label: "Capture", | ||
size: dimensions, | ||
format: "rgba8unorm-srgb", | ||
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, | ||
}); | ||
|
||
const encoder = device.createCommandEncoder(); | ||
const view = texture.createView(); | ||
const renderPass = encoder.beginRenderPass({ | ||
colorAttachments: [ | ||
{ | ||
view, | ||
storeOp: "store", | ||
loadOp: "clear", | ||
clearValue: [0, 1, 0, 1], | ||
}, | ||
], | ||
}); | ||
renderPass.setPipeline(renderPipeline); | ||
renderPass.draw(3, 1); | ||
renderPass.end(); | ||
|
||
encoder.copyTextureToBuffer( | ||
{ | ||
texture, | ||
}, | ||
{ | ||
buffer: outputBuffer, | ||
bytesPerRow: paddedBytesPerRow, | ||
rowsPerImage: 0, | ||
}, | ||
dimensions, | ||
); | ||
|
||
const bundle = encoder.finish(); | ||
device.queue.submit([bundle]); | ||
|
||
await outputBuffer.mapAsync(1); | ||
const data = new Uint8Array(outputBuffer.getMappedRange()); | ||
|
||
assertEquals( | ||
data, | ||
await Deno.readFile("cli/tests/testdata/webgpu/hellotriangle.out"), | ||
); | ||
|
||
outputBuffer.unmap(); | ||
|
||
device.destroy(); | ||
|
||
// TODO(lucacasonato): webgpu spec should add a explicit destroy method for | ||
// adapters. | ||
const resources = Object.keys(Deno.resources()); | ||
Deno.close(Number(resources[resources.length - 1])); | ||
}); | ||
|
||
Deno.test({ | ||
ignore: isWsl || isLinuxOrMacCI, | ||
}, async function webgpuAdapterHasFeatures() { | ||
const adapter = await navigator.gpu.requestAdapter(); | ||
assert(adapter); | ||
assert(adapter.features); | ||
const resources = Object.keys(Deno.resources()); | ||
Deno.close(Number(resources[resources.length - 1])); | ||
}); | ||
|
||
async function checkIsWsl() { | ||
return Deno.build.os === "linux" && await hasMicrosoftProcVersion(); | ||
|
||
async function hasMicrosoftProcVersion() { | ||
// https://github.com/microsoft/WSL/issues/423#issuecomment-221627364 | ||
try { | ||
const procVersion = await Deno.readTextFile("/proc/version"); | ||
return /microsoft/i.test(procVersion); | ||
} catch { | ||
return false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is 4th place we define this env var :) we should move it to
test_util.ts
in a follow up. Can you handle that @crowlKats?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure