From a0c1f22fd1af758843d7f8ee917da13fd17c061d Mon Sep 17 00:00:00 2001 From: Rezmason Date: Sun, 7 Aug 2022 19:17:22 -0700 Subject: [PATCH] Updating WebGPU project to satisfy Chrome Canary --- js/webgpu/bloomPass.js | 2 ++ js/webgpu/endPass.js | 1 + js/webgpu/main.js | 23 +++++++++++++---------- js/webgpu/palettePass.js | 1 + js/webgpu/rainPass.js | 2 ++ js/webgpu/utils.js | 7 +------ shaders/wgsl/bloomBlur.wgsl | 4 ++-- shaders/wgsl/bloomCombine.wgsl | 2 +- shaders/wgsl/endPass.wgsl | 4 ++-- shaders/wgsl/imagePass.wgsl | 2 +- shaders/wgsl/palettePass.wgsl | 4 ++-- shaders/wgsl/rainPass.wgsl | 16 ++++++++-------- shaders/wgsl/resurrectionPass.wgsl | 4 ++-- shaders/wgsl/stripePass.wgsl | 4 ++-- 14 files changed, 40 insertions(+), 36 deletions(-) diff --git a/js/webgpu/bloomPass.js b/js/webgpu/bloomPass.js index c5d3f51..f8e3ccb 100644 --- a/js/webgpu/bloomPass.js +++ b/js/webgpu/bloomPass.js @@ -75,6 +75,7 @@ export default ({ config, device }) => { const [blurShader, combineShader] = await Promise.all(assets); blurPipeline = device.createComputePipeline({ + layout: "auto", compute: { module: blurShader.module, entryPoint: "computeMain", @@ -82,6 +83,7 @@ export default ({ config, device }) => { }); combinePipeline = device.createComputePipeline({ + layout: "auto", compute: { module: combineShader.module, entryPoint: "computeMain", diff --git a/js/webgpu/endPass.js b/js/webgpu/endPass.js index f58ae8b..b539306 100644 --- a/js/webgpu/endPass.js +++ b/js/webgpu/endPass.js @@ -27,6 +27,7 @@ export default ({ device, canvasFormat, canvasContext }) => { const [imageShader] = await Promise.all(assets); renderPipeline = device.createRenderPipeline({ + layout: "auto", vertex: { module: imageShader.module, entryPoint: "vertMain", diff --git a/js/webgpu/main.js b/js/webgpu/main.js index 3987827..edfa107 100644 --- a/js/webgpu/main.js +++ b/js/webgpu/main.js @@ -1,5 +1,5 @@ import { structs } from "../../lib/gpu-buffer.js"; -import { getCanvasSize, makeUniformBuffer, makePipeline } from "./utils.js"; +import { makeUniformBuffer, makePipeline } from "./utils.js"; import makeRain from "./rainPass.js"; import makeBloomPass from "./bloomPass.js"; @@ -34,21 +34,21 @@ const effects = { export default async (canvas, config) => { await loadJS("lib/gl-matrix.js"); + const canvasFormat = navigator.gpu.getPreferredCanvasFormat(); const adapter = await navigator.gpu.requestAdapter(); const device = await adapter.requestDevice(); const canvasContext = canvas.getContext("webgpu"); - const canvasFormat = canvasContext.getPreferredFormat(adapter); // console.table(device.limits); - const canvasConfig = { + canvasContext.configure({ device, format: canvasFormat, - size: [NaN, NaN], + alphaMode: "opaque", usage: // GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST, - }; + }); const timeUniforms = structs.from(`struct Time { seconds : f32, frames : i32, };`).Time; const timeBuffer = makeUniformBuffer(device, timeUniforms); @@ -72,11 +72,14 @@ export default async (canvas, config) => { if (isNaN(start)) { start = now; } - const canvasSize = getCanvasSize(canvas); - if (canvasSize[0] !== canvasConfig.size[0] || canvasSize[1] !== canvasConfig.size[1]) { - canvasConfig.size = canvasSize; - canvasContext.configure(canvasConfig); - pipeline.build(canvasSize); + + const devicePixelRatio = window.devicePixelRatio ?? 1; + const canvasWidth = canvas.clientWidth * devicePixelRatio; + const canvasHeight = canvas.clientHeight * devicePixelRatio; + if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) { + canvas.width = canvasWidth; + canvas.height = canvasHeight; + pipeline.build([canvasWidth, canvasHeight]); } device.queue.writeBuffer(timeBuffer, 0, timeUniforms.toBuffer({ seconds: (now - start) / 1000, frames })); diff --git a/js/webgpu/palettePass.js b/js/webgpu/palettePass.js index b37d187..be13978 100644 --- a/js/webgpu/palettePass.js +++ b/js/webgpu/palettePass.js @@ -94,6 +94,7 @@ export default ({ config, device, timeBuffer }) => { const [paletteShader] = await Promise.all(assets); computePipeline = device.createComputePipeline({ + layout: "auto", compute: { module: paletteShader.module, entryPoint: "computeMain", diff --git a/js/webgpu/rainPass.js b/js/webgpu/rainPass.js index 919b8be..4900cd1 100644 --- a/js/webgpu/rainPass.js +++ b/js/webgpu/rainPass.js @@ -104,6 +104,7 @@ export default ({ config, device, timeBuffer }) => { sceneBuffer = makeUniformBuffer(device, sceneUniforms); computePipeline = device.createComputePipeline({ + layout: "auto", compute: { module: rainShader.module, entryPoint: "computeMain", @@ -117,6 +118,7 @@ export default ({ config, device, timeBuffer }) => { }; renderPipeline = device.createRenderPipeline({ + layout: "auto", vertex: { module: rainShader.module, entryPoint: "vertMain", diff --git a/js/webgpu/utils.js b/js/webgpu/utils.js index 01083db..321aafd 100644 --- a/js/webgpu/utils.js +++ b/js/webgpu/utils.js @@ -1,8 +1,3 @@ -const getCanvasSize = (canvas) => { - const devicePixelRatio = window.devicePixelRatio ?? 1; - return [canvas.clientWidth * devicePixelRatio, canvas.clientHeight * devicePixelRatio]; -}; - /* const loadTexture = async (device, url) => { const response = await fetch(url); @@ -126,4 +121,4 @@ const makePipeline = async (context, steps) => { }; }; -export { getCanvasSize, makeRenderTarget, makeComputeTarget, make1DTexture, loadTexture, loadShader, makeUniformBuffer, makePass, makePipeline, makeBindGroup }; +export { makeRenderTarget, makeComputeTarget, make1DTexture, loadTexture, loadShader, makeUniformBuffer, makePass, makePipeline, makeBindGroup }; diff --git a/shaders/wgsl/bloomBlur.wgsl b/shaders/wgsl/bloomBlur.wgsl index 8d413dd..cbf5d7b 100644 --- a/shaders/wgsl/bloomBlur.wgsl +++ b/shaders/wgsl/bloomBlur.wgsl @@ -1,4 +1,4 @@ -let ONE_OVER_SQRT_2PI = 0.39894; +const ONE_OVER_SQRT_2PI = 0.39894; struct Config { bloomRadius : f32, @@ -20,7 +20,7 @@ fn gaussianPDF(x : f32) -> f32 { ) / config.bloomRadius; } -@stage(compute) @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { +@compute @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { var coord = vec2(input.id.xy); var outputSize = textureDimensions(outputTex); diff --git a/shaders/wgsl/bloomCombine.wgsl b/shaders/wgsl/bloomCombine.wgsl index 1bbe978..027f6c9 100644 --- a/shaders/wgsl/bloomCombine.wgsl +++ b/shaders/wgsl/bloomCombine.wgsl @@ -19,7 +19,7 @@ struct ComputeInput { @builtin(global_invocation_id) id : vec3, }; -@stage(compute) @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { +@compute @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { var coord = vec2(input.id.xy); var outputSize = textureDimensions(outputTex); diff --git a/shaders/wgsl/endPass.wgsl b/shaders/wgsl/endPass.wgsl index c62363f..e149798 100644 --- a/shaders/wgsl/endPass.wgsl +++ b/shaders/wgsl/endPass.wgsl @@ -6,13 +6,13 @@ struct VertOutput { @location(0) uv : vec2, }; -@stage(vertex) fn vertMain(@builtin(vertex_index) index : u32) -> VertOutput { +@vertex fn vertMain(@builtin(vertex_index) index : u32) -> VertOutput { var uv = vec2(f32(index % 2u), f32((index + 1u) % 6u / 3u)); var position = vec4(uv * 2.0 - 1.0, 1.0, 1.0); return VertOutput(position, uv); } -@stage(fragment) fn fragMain(input : VertOutput) -> @location(0) vec4 { +@fragment fn fragMain(input : VertOutput) -> @location(0) vec4 { var uv = input.uv; uv.y = 1.0 - uv.y; return textureSample( tex, nearestSampler, uv ); diff --git a/shaders/wgsl/imagePass.wgsl b/shaders/wgsl/imagePass.wgsl index 5df32bc..16f6adf 100644 --- a/shaders/wgsl/imagePass.wgsl +++ b/shaders/wgsl/imagePass.wgsl @@ -19,7 +19,7 @@ fn getBrightness(uv : vec2) -> vec4 { return min((primary + bloom) * (2.0 - config.bloomStrength), vec4(1.0)); } -@stage(compute) @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { +@compute @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { // Resolve the invocation ID to a texel coordinate var coord = vec2(input.id.xy); diff --git a/shaders/wgsl/palettePass.wgsl b/shaders/wgsl/palettePass.wgsl index aac8b9d..4b78f2e 100644 --- a/shaders/wgsl/palettePass.wgsl +++ b/shaders/wgsl/palettePass.wgsl @@ -25,7 +25,7 @@ struct ComputeInput { @builtin(global_invocation_id) id : vec3, }; -let PI : f32 = 3.14159265359; +const PI : f32 = 3.14159265359; fn randomFloat( uv : vec2 ) -> f32 { let a = 12.9898; @@ -42,7 +42,7 @@ fn getBrightness(uv : vec2) -> vec4 { return min((primary + bloom) * (2.0 - config.bloomStrength), vec4(1.0)); } -@stage(compute) @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { +@compute @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { // Resolve the invocation ID to a texel coordinate var coord = vec2(input.id.xy); diff --git a/shaders/wgsl/rainPass.wgsl b/shaders/wgsl/rainPass.wgsl index 83572e5..068e49b 100644 --- a/shaders/wgsl/rainPass.wgsl +++ b/shaders/wgsl/rainPass.wgsl @@ -96,11 +96,11 @@ struct FragOutput { // Constants -let NUM_VERTICES_PER_QUAD : i32 = 6; // 2 * 3 -let PI : f32 = 3.14159265359; -let TWO_PI : f32 = 6.28318530718; -let SQRT_2 : f32 = 1.4142135623730951; -let SQRT_5 : f32 = 2.23606797749979; +const NUM_VERTICES_PER_QUAD : i32 = 6; // 2 * 3 +const PI : f32 = 3.14159265359; +const TWO_PI : f32 = 6.28318530718; +const SQRT_2 : f32 = 1.4142135623730951; +const SQRT_5 : f32 = 2.23606797749979; // Helper functions for generating randomness, borrowed from elsewhere @@ -277,7 +277,7 @@ fn computeResult (isFirstFrame : bool, previousResult : vec4, glyphPos : ve return result; } -@stage(compute) @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { +@compute @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { // Resolve the invocation ID to a cell coordinate var row = i32(input.id.y); @@ -305,7 +305,7 @@ fn computeResult (isFirstFrame : bool, previousResult : vec4, glyphPos : ve // vec2(1.0, 1.0), vec2(0.0, 1.0), vec2(1.0, 0.0) // ); -@stage(vertex) fn vertMain(input : VertInput) -> VertOutput { +@vertex fn vertMain(input : VertInput) -> VertOutput { var volumetric = bool(config.volumetric); @@ -383,7 +383,7 @@ fn getSymbolUV(glyphCycle : f32) -> vec2 { // Fragment shader -@stage(fragment) fn fragMain(input : VertOutput) -> FragOutput { +@fragment fn fragMain(input : VertOutput) -> FragOutput { var volumetric = bool(config.volumetric); var uv = input.uv; diff --git a/shaders/wgsl/resurrectionPass.wgsl b/shaders/wgsl/resurrectionPass.wgsl index a9ac073..642260f 100644 --- a/shaders/wgsl/resurrectionPass.wgsl +++ b/shaders/wgsl/resurrectionPass.wgsl @@ -20,7 +20,7 @@ struct ComputeInput { @builtin(global_invocation_id) id : vec3, }; -let PI : f32 = 3.14159265359; +const PI : f32 = 3.14159265359; fn randomFloat( uv : vec2 ) -> f32 { let a = 12.9898; @@ -56,7 +56,7 @@ fn hslToRgb(h : f32, s : f32, l : f32) -> vec3 { ); } -@stage(compute) @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { +@compute @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { // Resolve the invocation ID to a texel coordinate var coord = vec2(input.id.xy); diff --git a/shaders/wgsl/stripePass.wgsl b/shaders/wgsl/stripePass.wgsl index 7dbe76f..f6580dd 100644 --- a/shaders/wgsl/stripePass.wgsl +++ b/shaders/wgsl/stripePass.wgsl @@ -21,7 +21,7 @@ struct ComputeInput { @builtin(global_invocation_id) id : vec3, }; -let PI : f32 = 3.14159265359; +const PI : f32 = 3.14159265359; fn randomFloat( uv : vec2 ) -> f32 { let a = 12.9898; @@ -38,7 +38,7 @@ fn getBrightness(uv : vec2) -> vec4 { return min((primary + bloom) * (2.0 - config.bloomStrength), vec4(1.0)); } -@stage(compute) @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { +@compute @workgroup_size(32, 1, 1) fn computeMain(input : ComputeInput) { // Resolve the invocation ID to a texel coordinate var coord = vec2(input.id.xy);