Skip to content

Commit

Permalink
Show a dialog if WebGPU isn't available or there's an error (#423)
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 authored Jul 20, 2024
1 parent 6fb9300 commit fa7b022
Show file tree
Hide file tree
Showing 36 changed files with 227 additions and 67 deletions.
6 changes: 4 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 { quitIfWebGPUNotAvailable } from '../util';
import { mesh } from '../../meshes/teapot';

import opaqueWGSL from './opaque.wgsl';
Expand All @@ -12,8 +13,9 @@ 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 adapter = await navigator.gpu?.requestAdapter();
const device = await adapter?.requestDevice();
quitIfWebGPUNotAvailable(adapter, device);

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

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

const perfDisplayContainer = document.createElement('div');
perfDisplayContainer.style.color = 'white';
Expand Down
7 changes: 6 additions & 1 deletion 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 { quitIfAdapterNotAvailable, quitIfWebGPUNotAvailable } from '../util';

type BindGroupBindingLayout =
| GPUBufferBindingLayout
Expand Down Expand Up @@ -111,7 +112,9 @@ export const SampleInitFactoryWebGPU = async (
callback: SampleInitCallback3D
): Promise<SampleInit> => {
const init = async ({ canvas, gui, stats }) => {
const adapter = await navigator.gpu.requestAdapter();
const adapter = await navigator.gpu?.requestAdapter();
quitIfAdapterNotAvailable(adapter);

const timestampQueryAvailable = adapter.features.has('timestamp-query');
let device: GPUDevice;
if (timestampQueryAvailable) {
Expand All @@ -121,6 +124,8 @@ export const SampleInitFactoryWebGPU = async (
} else {
device = await adapter.requestDevice();
}
quitIfWebGPUNotAvailable(adapter, device);

const context = canvas.getContext('webgpu') as GPUCanvasContext;
const devicePixelRatio = window.devicePixelRatio;
canvas.width = canvas.clientWidth * devicePixelRatio;
Expand Down
6 changes: 4 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 { quitIfWebGPUNotAvailable } from '../util';

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

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

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

const devicePixelRatio = window.devicePixelRatio;
Expand Down
5 changes: 4 additions & 1 deletion sample/computeBoids/main.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { quitIfAdapterNotAvailable, quitIfWebGPUNotAvailable } 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 adapter = await navigator.gpu?.requestAdapter();
quitIfAdapterNotAvailable(adapter);

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

const perfDisplayContainer = document.createElement('div');
perfDisplayContainer.style.color = 'white';
Expand Down
8 changes: 6 additions & 2 deletions sample/cornell/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,25 @@ import Radiosity from './radiosity';
import Rasterizer from './rasterizer';
import Tonemapper from './tonemapper';
import Raytracer from './raytracer';
import { quitIfAdapterNotAvailable, quitIfWebGPUNotAvailable } 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();
const adapter = await navigator.gpu?.requestAdapter();
quitIfAdapterNotAvailable(adapter);

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 });
const device = await adapter?.requestDevice({ requiredFeatures });
quitIfWebGPUNotAvailable(adapter, device);

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

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

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

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

Expand Down
6 changes: 4 additions & 2 deletions sample/deferredRendering/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import fragmentWriteGBuffers from './fragmentWriteGBuffers.wgsl';
import vertexTextureQuad from './vertexTextureQuad.wgsl';
import fragmentGBuffersDebugView from './fragmentGBuffersDebugView.wgsl';
import fragmentDeferredRendering from './fragmentDeferredRendering.wgsl';
import { quitIfWebGPUNotAvailable } 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 adapter = await navigator.gpu?.requestAdapter();
const device = await adapter?.requestDevice();
quitIfWebGPUNotAvailable(adapter, device);

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

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

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

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

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

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

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

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

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

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

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

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

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

Expand Down
6 changes: 4 additions & 2 deletions sample/imageBlur/main.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { GUI } from 'dat.gui';
import blurWGSL from './blur.wgsl';
import fullscreenTexturedQuadWGSL from '../../shaders/fullscreenTexturedQuad.wgsl';
import { quitIfWebGPUNotAvailable } 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 adapter = await navigator.gpu?.requestAdapter();
const device = await adapter?.requestDevice();
quitIfWebGPUNotAvailable(adapter, device);

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

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

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

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

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

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

type TypedArrayView = Float32Array | Uint32Array;

Expand Down Expand Up @@ -45,8 +46,9 @@ function createVertexAndIndexBuffer(
};
}

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

const models = Object.values(modelData).map((data) =>
createVertexAndIndexBuffer(device, data)
Expand Down
6 changes: 4 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 { quitIfWebGPUNotAvailable } from '../util';

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

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const adapter = await navigator.gpu?.requestAdapter();
const device = await adapter?.requestDevice();
quitIfWebGPUNotAvailable(adapter, device);
const context = canvas.getContext('webgpu') as GPUCanvasContext;
const devicePixelRatio = window.devicePixelRatio;
canvas.width = canvas.clientWidth * devicePixelRatio;
Expand Down
7 changes: 5 additions & 2 deletions sample/occlusionQuery/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { GUI } from 'dat.gui';
import { mat4 } from 'wgpu-matrix';
import solidColorLitWGSL from './solidColorLit.wgsl';
import { quitIfWebGPUNotAvailable } from '../util';

const settings = {
animate: true,
Expand Down Expand Up @@ -30,8 +31,10 @@ export type TypedArrayConstructor =

const info = document.querySelector('#info');

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

const canvas = document.querySelector('canvas') as HTMLCanvasElement;
const context = canvas.getContext('webgpu') as GPUCanvasContext;
const devicePixelRatio = window.devicePixelRatio;
Expand Down
6 changes: 4 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 { quitIfWebGPUNotAvailable } from '../util';

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

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

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

Expand Down
2 changes: 2 additions & 0 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 { quitIfWebGPUNotAvailable } from '../util';

// See: https://www.google.com/search?q=fibonacci+sphere
function createFibonacciSphereVertices({
Expand All @@ -30,6 +31,7 @@ function createFibonacciSphereVertices({

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

// Get a WebGPU context from the canvas and configure it
const canvas = document.querySelector('canvas') as HTMLCanvasElement;
Expand Down
6 changes: 4 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 { quitIfWebGPUNotAvailable } from '../util';

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

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

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

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

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

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

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

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

Expand Down
Loading

0 comments on commit fa7b022

Please sign in to comment.