mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-14 12:29:30 -07:00
Adding named debug groups to the WebGPU passes, and switching the pipeline create calls to the async methods
This commit is contained in:
13
TODO.txt
13
TODO.txt
@@ -59,14 +59,9 @@ WebGPU
|
|||||||
Get rid of end pass once it's possible to copy a bgra8unorm to a canvas texture
|
Get rid of end pass once it's possible to copy a bgra8unorm to a canvas texture
|
||||||
Switch to rgba32float somehow?
|
Switch to rgba32float somehow?
|
||||||
Why isn't this straightforward?
|
Why isn't this straightforward?
|
||||||
|
Try shorthand
|
||||||
Best practices
|
Share a bind group and layout just for time?
|
||||||
https://www.youtube.com/watch?v=wYAvVUFQP2M&t=1360s
|
Try using a buffer for the stripe pass 1D texture
|
||||||
Use labels and debug groups everywhere
|
|
||||||
Create pipelines async-await
|
|
||||||
Use implicit pipeline layouts sparingly
|
|
||||||
I'm using implicit pipeline layouts
|
|
||||||
What would explicit layouts look like?
|
|
||||||
|
|
||||||
Improve loop support
|
Improve loop support
|
||||||
|
|
||||||
@@ -89,5 +84,7 @@ Deja vu effect: flashing rows
|
|||||||
Then use a thunder-like pattern to show and hide the flash
|
Then use a thunder-like pattern to show and hide the flash
|
||||||
|
|
||||||
gpu-buffer, working title
|
gpu-buffer, working title
|
||||||
|
Support type aliasing (type Q = array<i32, 5>)
|
||||||
|
Support shorthand (vec4f)
|
||||||
Build mocha tests, example project
|
Build mocha tests, example project
|
||||||
Give it its own repo, microsite
|
Give it its own repo, microsite
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const loadJS = (src) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
export default async (canvas, config) => {
|
export default async (canvas, config) => {
|
||||||
await Promise.all([loadJS("lib/regl.js"), loadJS("lib/gl-matrix.js")]);
|
await Promise.all([loadJS("lib/regl.min.js"), loadJS("lib/gl-matrix.js")]);
|
||||||
|
|
||||||
const resize = () => {
|
const resize = () => {
|
||||||
canvas.width = Math.ceil(canvas.clientWidth * config.resolution);
|
canvas.width = Math.ceil(canvas.clientWidth * config.resolution);
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export default ({ config, device }) => {
|
|||||||
// If there's no bloom to apply, return a no-op pass with an empty bloom texture
|
// If there's no bloom to apply, return a no-op pass with an empty bloom texture
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
const emptyTexture = makeComputeTarget(device, [1, 1]);
|
const emptyTexture = makeComputeTarget(device, [1, 1]);
|
||||||
return makePass(null, (size, inputs) => ({ ...inputs, bloom: emptyTexture }));
|
return makePass("No Bloom", null, (size, inputs) => ({ ...inputs, bloom: emptyTexture }));
|
||||||
}
|
}
|
||||||
|
|
||||||
const assets = [loadShader(device, "shaders/wgsl/bloomBlur.wgsl"), loadShader(device, "shaders/wgsl/bloomCombine.wgsl")];
|
const assets = [loadShader(device, "shaders/wgsl/bloomBlur.wgsl"), loadShader(device, "shaders/wgsl/bloomCombine.wgsl")];
|
||||||
@@ -74,21 +74,23 @@ export default ({ config, device }) => {
|
|||||||
const loaded = (async () => {
|
const loaded = (async () => {
|
||||||
const [blurShader, combineShader] = await Promise.all(assets);
|
const [blurShader, combineShader] = await Promise.all(assets);
|
||||||
|
|
||||||
blurPipeline = device.createComputePipeline({
|
[blurPipeline, combinePipeline] = await Promise.all([
|
||||||
|
device.createComputePipeline({
|
||||||
layout: "auto",
|
layout: "auto",
|
||||||
compute: {
|
compute: {
|
||||||
module: blurShader.module,
|
module: blurShader.module,
|
||||||
entryPoint: "computeMain",
|
entryPoint: "computeMain",
|
||||||
},
|
},
|
||||||
});
|
}),
|
||||||
|
|
||||||
combinePipeline = device.createComputePipeline({
|
device.createComputePipeline({
|
||||||
layout: "auto",
|
layout: "auto",
|
||||||
compute: {
|
compute: {
|
||||||
module: combineShader.module,
|
module: combineShader.module,
|
||||||
entryPoint: "computeMain",
|
entryPoint: "computeMain",
|
||||||
},
|
},
|
||||||
});
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
const blurUniforms = structs.from(blurShader.code).Config;
|
const blurUniforms = structs.from(blurShader.code).Config;
|
||||||
hBlurBuffer = makeUniformBuffer(device, blurUniforms, { bloomRadius, direction: [1, 0] });
|
hBlurBuffer = makeUniformBuffer(device, blurUniforms, { bloomRadius, direction: [1, 0] });
|
||||||
@@ -152,5 +154,5 @@ export default ({ config, device }) => {
|
|||||||
computePass.end();
|
computePass.end();
|
||||||
};
|
};
|
||||||
|
|
||||||
return makePass(loaded, build, run);
|
return makePass("Bloom", loaded, build, run);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export default ({ device, canvasFormat, canvasContext }) => {
|
|||||||
const loaded = (async () => {
|
const loaded = (async () => {
|
||||||
const [imageShader] = await Promise.all(assets);
|
const [imageShader] = await Promise.all(assets);
|
||||||
|
|
||||||
renderPipeline = device.createRenderPipeline({
|
renderPipeline = await device.createRenderPipelineAsync({
|
||||||
layout: "auto",
|
layout: "auto",
|
||||||
vertex: {
|
vertex: {
|
||||||
module: imageShader.module,
|
module: imageShader.module,
|
||||||
@@ -58,5 +58,5 @@ export default ({ device, canvasFormat, canvasContext }) => {
|
|||||||
renderPass.end();
|
renderPass.end();
|
||||||
};
|
};
|
||||||
|
|
||||||
return makePass(loaded, build, run);
|
return makePass("End", loaded, build, run);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export default ({ config, device }) => {
|
|||||||
|
|
||||||
backgroundTex = bgTex;
|
backgroundTex = bgTex;
|
||||||
|
|
||||||
computePipeline = device.createComputePipeline({
|
computePipeline = await device.createComputePipelineAsync({
|
||||||
layout: "auto",
|
layout: "auto",
|
||||||
compute: {
|
compute: {
|
||||||
module: imageShader.module,
|
module: imageShader.module,
|
||||||
@@ -61,5 +61,5 @@ export default ({ config, device }) => {
|
|||||||
computePass.end();
|
computePass.end();
|
||||||
};
|
};
|
||||||
|
|
||||||
return makePass(loaded, build, run);
|
return makePass("Image", loaded, build, run);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,14 +18,6 @@ window.onclick = (e) => {
|
|||||||
touchesChanged = true;
|
touchesChanged = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
uniforms: {
|
|
||||||
touches: () => touches,
|
|
||||||
aspectRatio: () => aspectRatio,
|
|
||||||
cameraAspectRatio,
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default ({ config, device, cameraTex, cameraAspectRatio, timeBuffer }) => {
|
export default ({ config, device, cameraTex, cameraAspectRatio, timeBuffer }) => {
|
||||||
const assets = [loadShader(device, "shaders/wgsl/mirrorPass.wgsl")];
|
const assets = [loadShader(device, "shaders/wgsl/mirrorPass.wgsl")];
|
||||||
|
|
||||||
@@ -47,7 +39,7 @@ export default ({ config, device, cameraTex, cameraAspectRatio, timeBuffer }) =>
|
|||||||
const loaded = (async () => {
|
const loaded = (async () => {
|
||||||
const [mirrorShader] = await Promise.all(assets);
|
const [mirrorShader] = await Promise.all(assets);
|
||||||
|
|
||||||
computePipeline = device.createComputePipeline({
|
computePipeline = await device.createComputePipelineAsync({
|
||||||
layout: "auto",
|
layout: "auto",
|
||||||
compute: {
|
compute: {
|
||||||
module: mirrorShader.module,
|
module: mirrorShader.module,
|
||||||
@@ -105,5 +97,5 @@ export default ({ config, device, cameraTex, cameraAspectRatio, timeBuffer }) =>
|
|||||||
|
|
||||||
start = Date.now();
|
start = Date.now();
|
||||||
|
|
||||||
return makePass(loaded, build, run);
|
return makePass("Mirror", loaded, build, run);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export default ({ config, device, timeBuffer }) => {
|
|||||||
const loaded = (async () => {
|
const loaded = (async () => {
|
||||||
const [paletteShader] = await Promise.all(assets);
|
const [paletteShader] = await Promise.all(assets);
|
||||||
|
|
||||||
computePipeline = device.createComputePipeline({
|
computePipeline = await device.createComputePipelineAsync({
|
||||||
layout: "auto",
|
layout: "auto",
|
||||||
compute: {
|
compute: {
|
||||||
module: paletteShader.module,
|
module: paletteShader.module,
|
||||||
@@ -137,5 +137,5 @@ export default ({ config, device, timeBuffer }) => {
|
|||||||
computePass.end();
|
computePass.end();
|
||||||
};
|
};
|
||||||
|
|
||||||
return makePass(loaded, build, run);
|
return makePass("Palette", loaded, build, run);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -104,21 +104,22 @@ export default ({ config, device, timeBuffer }) => {
|
|||||||
sceneUniforms = rainShaderUniforms.Scene;
|
sceneUniforms = rainShaderUniforms.Scene;
|
||||||
sceneBuffer = makeUniformBuffer(device, sceneUniforms);
|
sceneBuffer = makeUniformBuffer(device, sceneUniforms);
|
||||||
|
|
||||||
computePipeline = device.createComputePipeline({
|
|
||||||
layout: "auto",
|
|
||||||
compute: {
|
|
||||||
module: rainShader.module,
|
|
||||||
entryPoint: "computeMain",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const additiveBlendComponent = {
|
const additiveBlendComponent = {
|
||||||
operation: "add",
|
operation: "add",
|
||||||
srcFactor: "one",
|
srcFactor: "one",
|
||||||
dstFactor: "one",
|
dstFactor: "one",
|
||||||
};
|
};
|
||||||
|
|
||||||
renderPipeline = device.createRenderPipeline({
|
[computePipeline, renderPipeline] = await Promise.all([
|
||||||
|
device.createComputePipelineAsync({
|
||||||
|
layout: "auto",
|
||||||
|
compute: {
|
||||||
|
module: rainShader.module,
|
||||||
|
entryPoint: "computeMain",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
device.createRenderPipelineAsync({
|
||||||
layout: "auto",
|
layout: "auto",
|
||||||
vertex: {
|
vertex: {
|
||||||
module: rainShader.module,
|
module: rainShader.module,
|
||||||
@@ -144,7 +145,8 @@ export default ({ config, device, timeBuffer }) => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
computeBindGroup = makeBindGroup(device, computePipeline, 0, [configBuffer, timeBuffer, cellsBuffer]);
|
computeBindGroup = makeBindGroup(device, computePipeline, 0, [configBuffer, timeBuffer, cellsBuffer]);
|
||||||
renderBindGroup = makeBindGroup(device, renderPipeline, 0, [configBuffer, timeBuffer, sceneBuffer, linearSampler, msdfTexture.createView(), cellsBuffer]);
|
renderBindGroup = makeBindGroup(device, renderPipeline, 0, [configBuffer, timeBuffer, sceneBuffer, linearSampler, msdfTexture.createView(), cellsBuffer]);
|
||||||
@@ -196,5 +198,5 @@ export default ({ config, device, timeBuffer }) => {
|
|||||||
renderPass.end();
|
renderPass.end();
|
||||||
};
|
};
|
||||||
|
|
||||||
return makePass(loaded, build, run);
|
return makePass("Rain", loaded, build, run);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ export default ({ config, device, timeBuffer }) => {
|
|||||||
const loaded = (async () => {
|
const loaded = (async () => {
|
||||||
const [stripeShader] = await Promise.all(assets);
|
const [stripeShader] = await Promise.all(assets);
|
||||||
|
|
||||||
computePipeline = device.createComputePipeline({
|
computePipeline = await device.createComputePipelineAsync({
|
||||||
|
layout: "auto",
|
||||||
compute: {
|
compute: {
|
||||||
module: stripeShader.module,
|
module: stripeShader.module,
|
||||||
entryPoint: "computeMain",
|
entryPoint: "computeMain",
|
||||||
@@ -110,5 +111,5 @@ export default ({ config, device, timeBuffer }) => {
|
|||||||
computePass.end();
|
computePass.end();
|
||||||
};
|
};
|
||||||
|
|
||||||
return makePass(loaded, build, run);
|
return makePass("Stripe", loaded, build, run);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
|
// TODO: switch back to this impl once it doesn't break on FF Nightly
|
||||||
|
|
||||||
const loadTexture = async (device, url) => {
|
const loadTexture = async (device, url) => {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
const data = await response.blob();
|
const data = await response.blob();
|
||||||
@@ -105,10 +107,14 @@ const makeBindGroup = (device, pipeline, index, entries) =>
|
|||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
const makePass = (loaded, build, run) => ({
|
const makePass = (name, loaded, build, run) => ({
|
||||||
loaded: loaded ?? Promise.resolve(),
|
loaded: loaded ?? Promise.resolve(),
|
||||||
build: build ?? ((size, inputs) => inputs),
|
build: build ?? ((size, inputs) => inputs),
|
||||||
run: run ?? (() => {}),
|
run: (encoder) => {
|
||||||
|
encoder.pushDebugGroup(`Pass "${name}"`);
|
||||||
|
run?.(encoder);
|
||||||
|
encoder.popDebugGroup();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const makePipeline = async (context, steps) => {
|
const makePipeline = async (context, steps) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user