diff --git a/index.js b/index.js index 9a4c46f..be9b169 100644 --- a/index.js +++ b/index.js @@ -472,6 +472,43 @@ function checkWGSLLanguageFeatures(parent) { ])); } +async function checkWebXRSupport() { + // If XRGPUBinding is not available, WebXR is not supported. + if (!('XRGPUBinding' in window)) { + return 'not supported'; + } + + try { + // Check if immersive VR or AR sessions are supported. + const [isImmersiveVrSupported, isImmersiveArSupported] = await Promise.all([ + navigator.xr?.isSessionSupported('immersive-vr'), + navigator.xr?.isSessionSupported('immersive-ar'), + ]); + + // If no immersive sessions are supported, WebXR is not supported. + if (!(isImmersiveVrSupported || isImmersiveArSupported)) { + return 'not supported'; + } + + let xrCompatibleAccessed = false; + const xrAdapterOptions = { + get xrCompatible() { + xrCompatibleAccessed = true; + return true; + } + }; + + // Otherwise, request an adapter with XR compatible options. + const adapter = await navigator.gpu.requestAdapter(xrAdapterOptions); + + // If an adapter is found and it's XR compatible, WebXR is supported. + return adapter && xrCompatibleAccessed ? 'likely supported' : 'not supported'; + } catch (error) { + // If an error occurs during adapter request, WebXR support is unknown. + return 'unknown'; + } +} + async function checkMisc(parent, {haveFallback}) { const obj = {}; const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); @@ -479,6 +516,9 @@ async function checkMisc(parent, {haveFallback}) { if (!haveFallback) { obj['fallback adapter'] = 'not supported'; } + + obj['WebXR support'] = await checkWebXRSupport(); + try { const adapter = await navigator.gpu.requestAdapter(); const device = await adapter.requestDevice(); @@ -700,6 +740,7 @@ async function main() { { powerPreference: "low-power", }, { powerPreference: "low-power", forceFallbackAdapter: true, }, { compatibilityMode: true, featureLevel: "compatibility" }, + { xrCompatible: true }, ]; const adapterIds = new Map();