Skip to content

Commit

Permalink
Show a dialog if WebGPU isn't available or there's an error
Browse files Browse the repository at this point in the history
This won't catch JS exceptions in the middle of the actual sample, but
it at least shows a nice message when WebGPU is not available for some
reason, or there's an error (the browser doesn't support the sample).
  • Loading branch information
kainino0x committed Jun 15, 2024
1 parent 130fd05 commit 29c66ef
Show file tree
Hide file tree
Showing 34 changed files with 177 additions and 86 deletions.
4 changes: 2 additions & 2 deletions sample/a-buffer/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { mat4, vec3 } from 'wgpu-matrix';
import { GUI } from 'dat.gui';

import { initDeviceAndErrorDialog } from '../util';
import { mesh } from '../../meshes/teapot';

import opaqueWGSL from './opaque.wgsl';
Expand All @@ -12,8 +13,7 @@ function roundUp(n: number, k: number): number {
}

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
Expand Down
4 changes: 2 additions & 2 deletions sample/animometer/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { GUI } from 'dat.gui';
import animometerWGSL from './animometer.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const perfDisplayContainer = document.createElement('div');
perfDisplayContainer.style.color = 'white';
Expand Down
18 changes: 8 additions & 10 deletions sample/bitonicSort/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { GUI } from 'dat.gui';
import fullscreenTexturedQuad from '../../shaders/fullscreenTexturedQuad.wgsl';
import { initDeviceAndErrorDialog } from '../util';

type BindGroupBindingLayout =
| GPUBufferBindingLayout
Expand Down Expand Up @@ -111,16 +112,13 @@ export const SampleInitFactoryWebGPU = async (
callback: SampleInitCallback3D
): Promise<SampleInit> => {
const init = async ({ canvas, gui, stats }) => {
const adapter = await navigator.gpu.requestAdapter();
const timestampQueryAvailable = adapter.features.has('timestamp-query');
let device: GPUDevice;
if (timestampQueryAvailable) {
device = await adapter.requestDevice({
requiredFeatures: ['timestamp-query'],
});
} else {
device = await adapter.requestDevice();
}
let timestampQueryAvailable;
const device = await initDeviceAndErrorDialog({}, (adapter) => {
timestampQueryAvailable = adapter.features.has('timestamp-query');
return {
requiredFeatures: timestampQueryAvailable ? ['timestamp-query'] : [],
};
});
const context = canvas.getContext('webgpu') as GPUCanvasContext;
const devicePixelRatio = window.devicePixelRatio;
canvas.width = canvas.clientWidth * devicePixelRatio;
Expand Down
4 changes: 2 additions & 2 deletions sample/cameras/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import cubeWGSL from './cube.wgsl';
import { ArcballCamera, WASDCamera } from './camera';
import { createInputHandler } from './input';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;

Expand Down Expand Up @@ -39,8 +40,7 @@ gui.add(params, 'type', ['arcball', 'WASD']).onChange(() => {
oldCameraType = newCameraType;
});

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();
const context = canvas.getContext('webgpu') as GPUCanvasContext;

const devicePixelRatio = window.devicePixelRatio;
Expand Down
11 changes: 7 additions & 4 deletions sample/computeBoids/main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { initDeviceAndErrorDialog } from '../util';
import spriteWGSL from './sprite.wgsl';
import updateSpritesWGSL from './updateSprites.wgsl';
import { GUI } from 'dat.gui';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();

const hasTimestampQuery = adapter.features.has('timestamp-query');
const device = await adapter.requestDevice({
requiredFeatures: hasTimestampQuery ? ['timestamp-query'] : [],
let hasTimestampQuery;
const device = await initDeviceAndErrorDialog({}, (adapter) => {
hasTimestampQuery = adapter.features.has('timestamp-query');
return {
requiredFeatures: hasTimestampQuery ? ['timestamp-query'] : [],
};
});

const perfDisplayContainer = document.createElement('div');
Expand Down
25 changes: 14 additions & 11 deletions sample/cornell/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@ import Radiosity from './radiosity';
import Rasterizer from './rasterizer';
import Tonemapper from './tonemapper';
import Raytracer from './raytracer';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;

const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
const requiredFeatures: GPUFeatureName[] =
presentationFormat === 'bgra8unorm' ? ['bgra8unorm-storage'] : [];
const adapter = await navigator.gpu.requestAdapter();
for (const feature of requiredFeatures) {
if (!adapter.features.has(feature)) {
throw new Error(
`sample requires ${feature}, but is not supported by the adapter`
);
let presentationFormat;
const device = await initDeviceAndErrorDialog({}, (adapter) => {
presentationFormat = navigator.gpu.getPreferredCanvasFormat();
const requiredFeatures: GPUFeatureName[] =
presentationFormat === 'bgra8unorm' ? ['bgra8unorm-storage'] : [];
for (const feature of requiredFeatures) {
if (!adapter.features.has(feature)) {
throw new Error(
`sample requires ${feature}, but is not supported by the adapter`
);
}
}
}
const device = await adapter.requestDevice({ requiredFeatures });
return { requiredFeatures };
});

const params: {
renderer: 'rasterizer' | 'raytracer';
Expand Down
4 changes: 2 additions & 2 deletions sample/cubemap/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import {

import basicVertWGSL from '../../shaders/basic.vert.wgsl';
import sampleCubemapWGSL from './sampleCubemap.frag.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/deferredRendering/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import fragmentWriteGBuffers from './fragmentWriteGBuffers.wgsl';
import vertexTextureQuad from './vertexTextureQuad.wgsl';
import fragmentGBuffersDebugView from './fragmentGBuffersDebugView.wgsl';
import fragmentDeferredRendering from './fragmentDeferredRendering.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const kMaxNumLights = 1024;
const lightExtentMin = vec3.fromValues(-50, -30, -50);
const lightExtentMax = vec3.fromValues(50, 50, 50);

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/fractalCube/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import {

import basicVertWGSL from '../../shaders/basic.vert.wgsl';
import sampleSelfWGSL from './sampleSelf.frag.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/gameOfLife/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { GUI } from 'dat.gui';
import computeWGSL from './compute.wgsl';
import vertWGSL from './vert.wgsl';
import fragWGSL from './frag.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;
const devicePixelRatio = window.devicePixelRatio;
Expand Down
4 changes: 2 additions & 2 deletions sample/helloTriangle/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import triangleVertWGSL from '../../shaders/triangle.vert.wgsl';
import redFragWGSL from '../../shaders/red.frag.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/helloTriangleMSAA/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import triangleVertWGSL from '../../shaders/triangle.vert.wgsl';
import redFragWGSL from '../../shaders/red.frag.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/imageBlur/main.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { GUI } from 'dat.gui';
import blurWGSL from './blur.wgsl';
import fullscreenTexturedQuadWGSL from '../../shaders/fullscreenTexturedQuad.wgsl';
import { initDeviceAndErrorDialog } from '../util';

// Contants from the blur.wgsl shader.
const tileDim = 128;
const batch = [4, 4];

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/instancedCube/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import {

import instancedVertWGSL from './instanced.vert.wgsl';
import vertexPositionColorWGSL from '../../shaders/vertexPositionColor.frag.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/multipleCanvases/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable prettier/prettier */
import { mat4, mat3 } from 'wgpu-matrix';
import { modelData } from './models';
import { initDeviceAndErrorDialog } from '../util';

type TypedArrayView = Float32Array | Uint32Array;

Expand Down Expand Up @@ -46,8 +47,7 @@ function createVertexAndIndexBuffer(
};
}

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const models = Object.values(modelData).map(data => createVertexAndIndexBuffer(device, data));

Expand Down
4 changes: 2 additions & 2 deletions sample/normalMap/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
create3DRenderPipeline,
createTextureFromImage,
} from './utils';
import { initDeviceAndErrorDialog } from '../util';

const MAT4X4_BYTES = 64;
enum TextureAtlas {
Expand All @@ -17,8 +18,7 @@ enum TextureAtlas {
}

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();
const context = canvas.getContext('webgpu') as GPUCanvasContext;
const devicePixelRatio = window.devicePixelRatio;
canvas.width = canvas.clientWidth * devicePixelRatio;
Expand Down
4 changes: 2 additions & 2 deletions sample/particles/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { GUI } from 'dat.gui';

import particleWGSL from './particle.wgsl';
import probabilityMapWGSL from './probabilityMap.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const numParticles = 50000;
const particlePositionOffset = 0;
Expand All @@ -16,8 +17,7 @@ const particleInstanceByteSize =
0;

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/points/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import distanceSizedPointsVertWGSL from './distance-sized-points.vert.wgsl';
import fixedSizePointsVertWGSL from './fixed-size-points.vert.wgsl';
import orangeFragWGSL from './orange.frag.wgsl';
import texturedFragWGSL from './textured.frag.wgsl';
import { initDeviceAndErrorDialog } from '../util';

// See: https://www.google.com/search?q=fibonacci+sphere
function createFibonacciSphereVertices({
Expand All @@ -28,8 +29,7 @@ function createFibonacciSphereVertices({
return new Float32Array(vertices);
}

const adapter = await navigator.gpu?.requestAdapter();
const device = await adapter?.requestDevice();
const device = await initDeviceAndErrorDialog();

// Get a WebGPU context from the canvas and configure it
const canvas = document.querySelector('canvas') as HTMLCanvasElement;
Expand Down
4 changes: 2 additions & 2 deletions sample/renderBundles/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { createSphereMesh, SphereLayout } from '../../meshes/sphere';
import Stats from 'stats.js';

import meshWGSL from './mesh.wgsl';
import { initDeviceAndErrorDialog } from '../util';

interface Renderable {
vertices: GPUBuffer;
Expand All @@ -13,8 +14,7 @@ interface Renderable {
}

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const settings = {
useRenderBundles: true,
Expand Down
4 changes: 2 additions & 2 deletions sample/resizeCanvas/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import triangleVertWGSL from '../../shaders/triangle.vert.wgsl';
import redFragWGSL from '../../shaders/red.frag.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/resizeObserverHDDPI/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { GUI } from 'dat.gui';
import checkerWGSL from './checker.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/reversedZ/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import vertexTextureQuadWGSL from './vertexTextureQuad.wgsl';
import fragmentTextureQuadWGSL from './fragmentTextureQuad.wgsl';
import vertexPrecisionErrorPassWGSL from './vertexPrecisionErrorPass.wgsl';
import fragmentPrecisionErrorPassWGSL from './fragmentPrecisionErrorPass.wgsl';
import { initDeviceAndErrorDialog } from '../util';

// Two planes close to each other for depth precision test
const geometryVertexSize = 4 * 8; // Byte size of one geometry vertex.
Expand Down Expand Up @@ -65,8 +66,7 @@ const depthClearValues = {
};

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
4 changes: 2 additions & 2 deletions sample/rotatingCube/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import {

import basicVertWGSL from '../../shaders/basic.vert.wgsl';
import vertexPositionColorWGSL from '../../shaders/vertexPositionColor.frag.wgsl';
import { initDeviceAndErrorDialog } from '../util';

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const device = await initDeviceAndErrorDialog();

const context = canvas.getContext('webgpu') as GPUCanvasContext;

Expand Down
Loading

0 comments on commit 29c66ef

Please sign in to comment.