@jbrowse/render-core 5.0.0-beta.1 → 5.0.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/RenderCanvas.d.ts +3 -3
- package/esm/RenderCanvas.js +1 -1
- package/esm/RenderLifecycleMixin.d.ts +52 -20
- package/esm/RenderLifecycleMixin.js +89 -23
- package/esm/canvas2dUtils.d.ts +90 -23
- package/esm/canvas2dUtils.js +120 -37
- package/esm/colorRampLut.d.ts +5 -5
- package/esm/colorRampLut.js +6 -6
- package/esm/computePipeline.d.ts +14 -0
- package/esm/computePipeline.js +62 -0
- package/esm/contractReports.d.ts +54 -0
- package/esm/contractReports.js +112 -0
- package/esm/coverageBand.d.ts +13 -8
- package/esm/coverageBand.js +15 -5
- package/esm/coverageBandBuffers.d.ts +2 -9
- package/esm/coverageBandBuffers.js +1 -13
- package/esm/createRenderingBackend.d.ts +16 -20
- package/esm/createRenderingBackend.js +6 -4
- package/esm/displayPhase.d.ts +83 -104
- package/esm/displayPhase.js +42 -82
- package/esm/encodeMemo.d.ts +14 -0
- package/esm/encodeMemo.js +48 -0
- package/esm/gpuContextLostError.d.ts +30 -0
- package/esm/gpuContextLostError.js +40 -0
- package/esm/gpuDevice.d.ts +29 -10
- package/esm/gpuDevice.js +35 -16
- package/esm/graphicsCapabilities.d.ts +27 -19
- package/esm/graphicsCapabilities.js +41 -19
- package/esm/hal/createHal.d.ts +4 -5
- package/esm/hal/createHal.js +15 -5
- package/esm/hal/deviceGpuCache.d.ts +25 -30
- package/esm/hal/deviceGpuCache.js +85 -97
- package/esm/hal/gpuHalBase.d.ts +5 -4
- package/esm/hal/gpuHalBase.js +25 -14
- package/esm/hal/index.d.ts +2 -2
- package/esm/hal/index.js +1 -1
- package/esm/hal/mockHal.d.ts +15 -10
- package/esm/hal/mockHal.js +31 -18
- package/esm/hal/oomReporter.d.ts +7 -0
- package/esm/hal/oomReporter.js +10 -0
- package/esm/hal/passIds.d.ts +8 -7
- package/esm/hal/passIds.js +11 -10
- package/esm/hal/regionRegistry.d.ts +0 -1
- package/esm/hal/regionRegistry.js +3 -15
- package/esm/hal/types.d.ts +53 -18
- package/esm/hal/webgl2Hal.d.ts +23 -6
- package/esm/hal/webgl2Hal.js +158 -155
- package/esm/hal/webgpuHal.d.ts +29 -13
- package/esm/hal/webgpuHal.js +220 -153
- package/esm/installUpload.d.ts +16 -3
- package/esm/installUpload.js +13 -41
- package/esm/instanceCache.d.ts +10 -7
- package/esm/instanceCache.js +14 -15
- package/esm/instancePass.d.ts +2 -1
- package/esm/mapUploadSync.d.ts +2 -10
- package/esm/mapUploadSync.js +2 -3
- package/esm/marks/barMark.d.ts +30 -0
- package/esm/marks/barMark.js +149 -0
- package/esm/marks/colorFill.d.ts +17 -0
- package/esm/marks/colorFill.js +26 -0
- package/esm/marks/drawAgainstHit.d.ts +113 -0
- package/esm/marks/drawAgainstHit.js +407 -0
- package/esm/marks/ellipseDistance.d.ts +10 -0
- package/esm/marks/ellipseDistance.js +136 -0
- package/esm/marks/glyphPaint.d.ts +36 -0
- package/esm/marks/glyphPaint.js +77 -0
- package/esm/marks/index.d.ts +33 -0
- package/esm/marks/index.js +20 -0
- package/esm/marks/lineMark.d.ts +37 -0
- package/esm/marks/lineMark.js +416 -0
- package/esm/marks/linkMark.d.ts +76 -0
- package/esm/marks/linkMark.js +585 -0
- package/esm/marks/markBackend.d.ts +118 -0
- package/esm/marks/markBackend.js +196 -0
- package/esm/marks/markHit.d.ts +32 -0
- package/esm/marks/markHit.js +61 -0
- package/esm/marks/markInk.d.ts +18 -0
- package/esm/marks/markInk.js +71 -0
- package/esm/marks/markPaint.d.ts +14 -0
- package/esm/marks/markPaint.js +32 -0
- package/esm/marks/markPlan.d.ts +25 -0
- package/esm/marks/markPlan.js +20 -0
- package/esm/marks/markRamp.d.ts +74 -0
- package/esm/marks/markRamp.js +205 -0
- package/esm/marks/nearestMarkHit.d.ts +55 -0
- package/esm/marks/nearestMarkHit.js +158 -0
- package/esm/marks/pathRecorder.d.ts +14 -0
- package/esm/marks/pathRecorder.js +80 -0
- package/esm/marks/pointMark.d.ts +42 -0
- package/esm/marks/pointMark.js +125 -0
- package/esm/marks/rowLane.d.ts +39 -0
- package/esm/marks/rowLane.js +41 -0
- package/esm/marks/rowSpanIndex.d.ts +30 -0
- package/esm/marks/rowSpanIndex.js +151 -0
- package/esm/marks/rowTable.d.ts +41 -0
- package/esm/marks/rowTable.js +75 -0
- package/esm/marks/ruleMark.d.ts +21 -0
- package/esm/marks/ruleMark.js +91 -0
- package/esm/marks/spanMark.d.ts +42 -0
- package/esm/marks/spanMark.js +81 -0
- package/esm/marks/types.d.ts +261 -0
- package/esm/marks/types.js +175 -0
- package/esm/marks/valueScale.d.ts +23 -0
- package/esm/marks/valueScale.js +11 -0
- package/esm/namedReactions.d.ts +3 -4
- package/esm/namedReactions.js +3 -4
- package/esm/perRegionRenderingBackend.d.ts +21 -3
- package/esm/perRegionRenderingBackend.js +37 -3
- package/esm/regionDataMap.d.ts +2 -2
- package/esm/regionDataMap.js +25 -23
- package/esm/renderBlock.d.ts +14 -0
- package/esm/renderBlock.js +25 -0
- package/esm/renderingBackendBase.d.ts +20 -14
- package/esm/renderingBackendBase.js +12 -7
- package/esm/scoreScale.d.ts +27 -0
- package/esm/scoreScale.js +88 -0
- package/esm/shaders/barMark.generated.d.ts +3 -0
- package/esm/shaders/barMark.generated.js +7 -0
- package/esm/shaders/barMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/barMark.glsl.generated.js +4 -0
- package/esm/shaders/barMark.iface.generated.d.ts +90 -0
- package/esm/shaders/barMark.iface.generated.js +205 -0
- package/esm/shaders/barMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/barMark.wgsl.generated.js +3 -0
- package/esm/shaders/capsule.js.generated.d.ts +1 -0
- package/esm/shaders/capsule.js.generated.js +11 -0
- package/esm/shaders/clipStrip.generated.d.ts +2 -0
- package/esm/shaders/clipStrip.generated.js +4 -0
- package/esm/shaders/clipStrip.js.generated.d.ts +1 -0
- package/esm/shaders/clipStrip.js.generated.js +21 -0
- package/esm/shaders/colorRampLut.js.generated.d.ts +1 -0
- package/esm/shaders/colorRampLut.js.generated.js +17 -0
- package/esm/shaders/coverageBar.generated.d.ts +2 -3
- package/esm/shaders/coverageBar.generated.js +4 -3
- package/esm/shaders/coverageBar.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageBar.glsl.generated.js +4 -0
- package/esm/shaders/coverageBar.iface.generated.js +1 -1
- package/esm/shaders/coverageBar.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageBar.wgsl.generated.js +3 -0
- package/esm/shaders/coverageClip.generated.d.ts +3 -0
- package/esm/shaders/coverageClip.generated.js +7 -0
- package/esm/shaders/coverageClip.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageClip.glsl.generated.js +4 -0
- package/esm/shaders/coverageClip.iface.generated.d.ts +85 -0
- package/esm/shaders/coverageClip.iface.generated.js +114 -0
- package/esm/shaders/coverageClip.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageClip.wgsl.generated.js +3 -0
- package/esm/shaders/coverageIndicator.generated.d.ts +2 -3
- package/esm/shaders/coverageIndicator.generated.js +4 -3
- package/esm/shaders/coverageIndicator.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageIndicator.glsl.generated.js +4 -0
- package/esm/shaders/coverageIndicator.iface.generated.js +1 -1
- package/esm/shaders/coverageIndicator.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageIndicator.wgsl.generated.js +3 -0
- package/esm/shaders/coverageInterbase.generated.d.ts +2 -3
- package/esm/shaders/coverageInterbase.generated.js +4 -3
- package/esm/shaders/coverageInterbase.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageInterbase.glsl.generated.js +4 -0
- package/esm/shaders/coverageInterbase.iface.generated.js +1 -1
- package/esm/shaders/coverageInterbase.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageInterbase.wgsl.generated.js +3 -0
- package/esm/shaders/coverageMod.generated.d.ts +2 -3
- package/esm/shaders/coverageMod.generated.js +4 -3
- package/esm/shaders/coverageMod.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageMod.glsl.generated.js +4 -0
- package/esm/shaders/coverageMod.iface.generated.js +1 -1
- package/esm/shaders/coverageMod.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageMod.wgsl.generated.js +3 -0
- package/esm/shaders/coverageSnp.generated.d.ts +2 -3
- package/esm/shaders/coverageSnp.generated.js +4 -3
- package/esm/shaders/coverageSnp.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageSnp.glsl.generated.js +4 -0
- package/esm/shaders/coverageSnp.iface.generated.js +1 -1
- package/esm/shaders/coverageSnp.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageSnp.wgsl.generated.js +3 -0
- package/esm/shaders/curveDistance.js.generated.d.ts +5 -0
- package/esm/shaders/curveDistance.js.generated.js +87 -0
- package/esm/shaders/hpmath.js.generated.d.ts +2 -1
- package/esm/shaders/hpmath.js.generated.js +5 -2
- package/esm/shaders/lineCenterMark.generated.d.ts +3 -0
- package/esm/shaders/lineCenterMark.generated.js +7 -0
- package/esm/shaders/lineCenterMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/lineCenterMark.glsl.generated.js +4 -0
- package/esm/shaders/lineCenterMark.iface.generated.d.ts +104 -0
- package/esm/shaders/lineCenterMark.iface.generated.js +237 -0
- package/esm/shaders/lineCenterMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/lineCenterMark.wgsl.generated.js +3 -0
- package/esm/shaders/lineCommon.generated.d.ts +2 -0
- package/esm/shaders/lineCommon.generated.js +4 -0
- package/esm/shaders/lineStepMark.generated.d.ts +3 -0
- package/esm/shaders/lineStepMark.generated.js +7 -0
- package/esm/shaders/lineStepMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/lineStepMark.glsl.generated.js +4 -0
- package/esm/shaders/lineStepMark.iface.generated.d.ts +98 -0
- package/esm/shaders/lineStepMark.iface.generated.js +225 -0
- package/esm/shaders/lineStepMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/lineStepMark.wgsl.generated.js +3 -0
- package/esm/shaders/linkMark.consts.generated.d.ts +14 -0
- package/esm/shaders/linkMark.consts.generated.js +16 -0
- package/esm/shaders/linkMark.generated.d.ts +4 -0
- package/esm/shaders/linkMark.generated.js +8 -0
- package/esm/shaders/linkMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/linkMark.glsl.generated.js +4 -0
- package/esm/shaders/linkMark.iface.generated.d.ts +142 -0
- package/esm/shaders/linkMark.iface.generated.js +1829 -0
- package/esm/shaders/linkMark.js.generated.d.ts +7 -0
- package/esm/shaders/linkMark.js.generated.js +159 -0
- package/esm/shaders/linkMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/linkMark.wgsl.generated.js +3 -0
- package/esm/shaders/markColor.generated.d.ts +9 -0
- package/esm/shaders/markColor.generated.js +11 -0
- package/esm/shaders/pointGlyph.js.generated.d.ts +2 -0
- package/esm/shaders/pointGlyph.js.generated.js +15 -0
- package/esm/shaders/pointMark.consts.generated.d.ts +7 -0
- package/esm/shaders/pointMark.consts.generated.js +9 -0
- package/esm/shaders/pointMark.generated.d.ts +4 -0
- package/esm/shaders/pointMark.generated.js +8 -0
- package/esm/shaders/pointMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/pointMark.glsl.generated.js +4 -0
- package/esm/shaders/pointMark.iface.generated.d.ts +98 -0
- package/esm/shaders/pointMark.iface.generated.js +219 -0
- package/esm/shaders/pointMark.js.generated.d.ts +3 -0
- package/esm/shaders/pointMark.js.generated.js +93 -0
- package/esm/shaders/pointMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/pointMark.wgsl.generated.js +3 -0
- package/esm/shaders/rowRect.generated.d.ts +0 -1
- package/esm/shaders/rowRect.generated.js +0 -1
- package/esm/shaders/rowTable.generated.d.ts +1 -0
- package/esm/shaders/rowTable.generated.js +3 -0
- package/esm/shaders/rowTable.js.generated.d.ts +5 -0
- package/esm/shaders/rowTable.js.generated.js +29 -0
- package/esm/shaders/scoreScale.generated.d.ts +2 -0
- package/esm/shaders/scoreScale.generated.js +4 -0
- package/esm/shaders/scoreScale.js.generated.d.ts +1 -0
- package/esm/shaders/scoreScale.js.generated.js +50 -23
- package/esm/shaders/spanMark.generated.d.ts +3 -0
- package/esm/shaders/spanMark.generated.js +7 -0
- package/esm/shaders/spanMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/spanMark.glsl.generated.js +4 -0
- package/esm/shaders/spanMark.iface.generated.d.ts +81 -0
- package/esm/shaders/spanMark.iface.generated.js +215 -0
- package/esm/shaders/spanMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/spanMark.wgsl.generated.js +3 -0
- package/esm/sharedBackendKey.d.ts +18 -0
- package/esm/{keyedRenderingBackend.js → sharedBackendKey.js} +5 -0
- package/esm/slangPass.d.ts +17 -11
- package/esm/slangPass.js +12 -4
- package/esm/useGraphicsCapabilities.d.ts +1 -1
- package/esm/useGraphicsCapabilities.js +1 -1
- package/esm/useRenderingBackend.d.ts +13 -13
- package/esm/useRenderingBackend.js +58 -20
- package/esm/webgpuUtils.d.ts +3 -11
- package/esm/webgpuUtils.js +12 -33
- package/package.json +32 -7
- package/src/shaders/antialias.slang +46 -0
- package/src/shaders/arcHull.test.ts +267 -0
- package/src/shaders/barMark.generated.ts +11 -0
- package/src/shaders/barMark.glsl.generated.ts +6 -0
- package/src/shaders/barMark.iface.generated.ts +285 -0
- package/src/shaders/barMark.slang +167 -0
- package/src/shaders/barMark.wgsl.generated.ts +4 -0
- package/src/shaders/capsule.js.generated.ts +14 -0
- package/src/shaders/capsule.slang +13 -5
- package/src/shaders/clipStrip.generated.ts +6 -0
- package/src/shaders/clipStrip.js.generated.ts +22 -0
- package/src/shaders/clipStrip.slang +34 -0
- package/src/shaders/clipStrip.test.ts +39 -0
- package/src/shaders/colorPack.slang +5 -1
- package/src/shaders/colorRampLut.js.generated.ts +22 -0
- package/src/shaders/colorRampLut.slang +15 -1
- package/src/shaders/coverageBand.slang +64 -32
- package/src/shaders/coverageBar.generated.ts +6 -5
- package/src/shaders/coverageBar.glsl.generated.ts +6 -0
- package/src/shaders/coverageBar.iface.generated.ts +1 -1
- package/src/shaders/coverageBar.slang +10 -10
- package/src/shaders/coverageBar.wgsl.generated.ts +4 -0
- package/src/shaders/coverageClip.generated.ts +11 -0
- package/src/shaders/coverageClip.glsl.generated.ts +6 -0
- package/src/shaders/coverageClip.iface.generated.ts +172 -0
- package/src/shaders/coverageClip.slang +38 -0
- package/src/shaders/coverageClip.wgsl.generated.ts +4 -0
- package/src/shaders/coverageIndicator.generated.ts +6 -5
- package/src/shaders/coverageIndicator.glsl.generated.ts +6 -0
- package/src/shaders/coverageIndicator.iface.generated.ts +1 -1
- package/src/shaders/coverageIndicator.wgsl.generated.ts +4 -0
- package/src/shaders/coverageInterbase.generated.ts +6 -5
- package/src/shaders/coverageInterbase.glsl.generated.ts +6 -0
- package/src/shaders/coverageInterbase.iface.generated.ts +1 -1
- package/src/shaders/coverageInterbase.wgsl.generated.ts +4 -0
- package/src/shaders/coverageMod.generated.ts +6 -5
- package/src/shaders/coverageMod.glsl.generated.ts +6 -0
- package/src/shaders/coverageMod.iface.generated.ts +1 -1
- package/src/shaders/coverageMod.wgsl.generated.ts +4 -0
- package/src/shaders/coverageSnp.generated.ts +6 -5
- package/src/shaders/coverageSnp.glsl.generated.ts +6 -0
- package/src/shaders/coverageSnp.iface.generated.ts +1 -1
- package/src/shaders/coverageSnp.wgsl.generated.ts +4 -0
- package/src/shaders/curveDistance.js.generated.ts +91 -0
- package/src/shaders/curveDistance.slang +265 -0
- package/src/shaders/hpClampFloor.test.ts +87 -0
- package/src/shaders/hpmath.js.generated.ts +6 -2
- package/src/shaders/hpmath.slang +100 -48
- package/src/shaders/insetValueScale.test.ts +67 -0
- package/src/shaders/lineCenterMark.generated.ts +11 -0
- package/src/shaders/lineCenterMark.glsl.generated.ts +6 -0
- package/src/shaders/lineCenterMark.iface.generated.ts +328 -0
- package/src/shaders/lineCenterMark.slang +127 -0
- package/src/shaders/lineCenterMark.wgsl.generated.ts +4 -0
- package/src/shaders/lineCommon.generated.ts +6 -0
- package/src/shaders/lineCommon.slang +102 -0
- package/src/shaders/lineStepMark.generated.ts +11 -0
- package/src/shaders/lineStepMark.glsl.generated.ts +6 -0
- package/src/shaders/lineStepMark.iface.generated.ts +311 -0
- package/src/shaders/lineStepMark.slang +125 -0
- package/src/shaders/lineStepMark.wgsl.generated.ts +4 -0
- package/src/shaders/linkMark.consts.generated.ts +30 -0
- package/src/shaders/linkMark.generated.ts +12 -0
- package/src/shaders/linkMark.glsl.generated.ts +6 -0
- package/src/shaders/linkMark.iface.generated.ts +1954 -0
- package/src/shaders/linkMark.js.generated.ts +167 -0
- package/src/shaders/linkMark.slang +439 -0
- package/src/shaders/linkMark.wgsl.generated.ts +4 -0
- package/src/shaders/markColor.generated.ts +20 -0
- package/src/shaders/markColor.slang +128 -0
- package/src/shaders/pointGlyph.js.generated.ts +20 -0
- package/src/shaders/pointGlyph.slang +23 -7
- package/src/shaders/pointGlyphPad.test.ts +242 -0
- package/src/shaders/pointMark.consts.generated.ts +16 -0
- package/src/shaders/pointMark.generated.ts +12 -0
- package/src/shaders/pointMark.glsl.generated.ts +6 -0
- package/src/shaders/pointMark.iface.generated.ts +304 -0
- package/src/shaders/pointMark.js.generated.ts +99 -0
- package/src/shaders/pointMark.slang +227 -0
- package/src/shaders/pointMark.wgsl.generated.ts +4 -0
- package/src/shaders/rowRect.generated.ts +0 -2
- package/src/shaders/rowRect.slang +39 -58
- package/src/shaders/rowTable.generated.ts +4 -0
- package/src/shaders/rowTable.js.generated.ts +37 -0
- package/src/shaders/rowTable.slang +98 -0
- package/src/shaders/scoreScale.generated.ts +6 -0
- package/src/shaders/scoreScale.js.generated.ts +48 -23
- package/src/shaders/scoreScale.slang +49 -55
- package/src/shaders/sdEllipse.test.ts +211 -0
- package/src/shaders/spanMark.generated.ts +11 -0
- package/src/shaders/spanMark.glsl.generated.ts +6 -0
- package/src/shaders/spanMark.iface.generated.ts +289 -0
- package/src/shaders/spanMark.slang +77 -0
- package/src/shaders/spanMark.wgsl.generated.ts +4 -0
- package/src/shaders/valueScale.slang +26 -0
- package/src/shaders/wideCircleLeg.test.ts +85 -0
- package/esm/globalRenderingBackend.d.ts +0 -90
- package/esm/globalRenderingBackend.js +0 -53
- package/esm/keyedRenderingBackend.d.ts +0 -41
package/esm/gpuDevice.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import type { RendererName } from './graphicsCapabilities.ts';
|
|
1
2
|
interface GpuDeviceCell {
|
|
2
3
|
device: GPUDevice | null;
|
|
3
4
|
/** Serializes concurrent calls during async init and after recovery. */
|
|
4
5
|
devicePromise: Promise<GPUDevice | null> | null;
|
|
5
6
|
/**
|
|
6
7
|
* Proof that this machine's WebGPU works, set the first time a device is
|
|
7
|
-
* acquired.
|
|
8
|
+
* acquired. The flag tells the two causes of a failed acquisition apart,
|
|
9
|
+
* because the two
|
|
8
10
|
* causes are indistinguishable at the call site and want opposite handling:
|
|
9
11
|
*
|
|
10
12
|
* - Before it, failure means "no WebGPU here" — the ordinary path on most
|
|
@@ -15,9 +17,9 @@ interface GpuDeviceCell {
|
|
|
15
17
|
* `requestAdapter` still declines. So this is not a rare race — it is the
|
|
16
18
|
* expected timing of the one path that re-acquires.
|
|
17
19
|
*
|
|
18
|
-
*
|
|
19
|
-
* this machine" (its own words)
|
|
20
|
-
*
|
|
20
|
+
* `createGpuHal` reads a cached failure of the second kind as "no WebGPU on
|
|
21
|
+
* this machine" (its own words) and pins the whole page to WebGL2 until a
|
|
22
|
+
* reload. So past this flag a failure is retried and never cached.
|
|
21
23
|
*/
|
|
22
24
|
hadDevice: boolean;
|
|
23
25
|
deviceLostListeners: Set<() => void>;
|
|
@@ -30,19 +32,34 @@ interface GpuDeviceCell {
|
|
|
30
32
|
* @see setGpuOverride
|
|
31
33
|
*/
|
|
32
34
|
gpuOverride: string | null;
|
|
35
|
+
/**
|
|
36
|
+
* The rung the last `createGpuHal` returned, so `effectiveRenderer` reports
|
|
37
|
+
* what drew rather than what the probe predicted. Optional because a cell an
|
|
38
|
+
* older copy built has none, and "nothing built yet" is a real state there.
|
|
39
|
+
*/
|
|
40
|
+
builtRenderer?: RendererName;
|
|
41
|
+
/**
|
|
42
|
+
* The page's first `requestAdapter`, which device acquisition and the
|
|
43
|
+
* capability probe share: on a machine without WebGPU each ask takes a few
|
|
44
|
+
* hundred milliseconds to decline. Optional for the same reason as
|
|
45
|
+
* `builtRenderer`.
|
|
46
|
+
*/
|
|
47
|
+
firstAdapter?: Promise<GPUAdapter | null>;
|
|
33
48
|
}
|
|
34
49
|
declare global {
|
|
35
50
|
var __jbrowseRenderCoreGpuDeviceV1: GpuDeviceCell | undefined;
|
|
36
51
|
}
|
|
37
52
|
export declare function onDeviceLost(listener: () => void): () => void;
|
|
53
|
+
/** The page's first adapter request; see `GpuDeviceCell.firstAdapter` */
|
|
54
|
+
export declare function requestFirstAdapter(): Promise<GPUAdapter | null>;
|
|
38
55
|
/**
|
|
39
56
|
* The renderers `?renderer=` can pin the page to. `canvas` is a spelling of
|
|
40
57
|
* `canvas2d` kept because it is in the wild.
|
|
41
58
|
*
|
|
42
|
-
* A pin means *only* that rung — `createGpuHal` does not fall past it.
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
59
|
+
* A pin means *only* that rung — `createGpuHal` does not fall past it. The flag
|
|
60
|
+
* is for comparing backends, and a comparison that renders with a different
|
|
61
|
+
* backend than the one pinned is worse than no comparison. The failure shows
|
|
62
|
+
* instead, as a `renderError` carrying the pin that could
|
|
46
63
|
* not be honored, with the banner's "disable GPU" as the way out.
|
|
47
64
|
*/
|
|
48
65
|
export declare const GPU_OVERRIDES: readonly ['webgpu', 'webgl', 'canvas2d', 'canvas'];
|
|
@@ -56,11 +73,13 @@ export type GpuOverride = (typeof GPU_OVERRIDES)[number];
|
|
|
56
73
|
* `--renderer` flag), so validating here is validating once at the only place
|
|
57
74
|
* an unchecked value enters. An unrecognized one clears the pin and says so:
|
|
58
75
|
* before this, `?renderer=WebGL` or a typo was indistinguishable from passing
|
|
59
|
-
* nothing at all,
|
|
60
|
-
*
|
|
76
|
+
* nothing at all, and a person debugging a renderer got the default ladder
|
|
77
|
+
* with no sign the pin was ignored.
|
|
61
78
|
*/
|
|
62
79
|
export declare function setGpuOverride(value: string | null): void;
|
|
63
80
|
export declare function getGpuOverride(): string | null;
|
|
81
|
+
export declare function setBuiltRenderer(name: RendererName): void;
|
|
82
|
+
export declare function getBuiltRenderer(): RendererName | undefined;
|
|
64
83
|
/**
|
|
65
84
|
* Whether the GPU is off for the whole page — either pinned by `?renderer=` at
|
|
66
85
|
* startup or switched off from a display's GPU-error banner after an
|
package/esm/gpuDevice.js
CHANGED
|
@@ -11,22 +11,23 @@
|
|
|
11
11
|
* button on the context-loss banner, which `packages/render-core/CLAUDE.md`
|
|
12
12
|
* names as the only sanctioned fallback path once a backend is built.
|
|
13
13
|
*
|
|
14
|
-
* A
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* A plugin that bundled render-core is the case this exists for. Every plugin
|
|
15
|
+
* built before ADR-128 did, so a third-party display can carry its own copy of
|
|
16
|
+
* this module; with module locals its `gpuOverride` would start
|
|
17
17
|
* null and stay null, and the user who pins `?renderer=canvas2d` or clicks
|
|
18
18
|
* "disable GPU" after a crash would watch the plugin ignore both and take
|
|
19
|
-
* WebGPU anyway. Sharing the cell fixes that
|
|
20
|
-
* frozen `ReExports` ABI — which is the trade ADR-030 declined, and rightly.
|
|
19
|
+
* WebGPU anyway. Sharing the cell fixes that for every copy, served or bundled.
|
|
21
20
|
*
|
|
22
21
|
* **The shape is a cross-version contract.** Copies at different render-core
|
|
23
22
|
* versions meet here, and whichever loads first wins the initialization, so a
|
|
24
23
|
* field added later would read `undefined` on a cell built by an older copy.
|
|
25
24
|
* Changing this interface therefore means bumping the `V1` in the global's
|
|
26
25
|
* name, which costs the sharing between the two versions — the point of the
|
|
27
|
-
* suffix is that losing it is a decision rather than a silent misread.
|
|
28
|
-
*
|
|
29
|
-
*
|
|
26
|
+
* suffix is that losing it is a decision rather than a silent misread. The one
|
|
27
|
+
* exception is an optional field whose `undefined` is an honest state, as
|
|
28
|
+
* `builtRenderer`'s is. Reset in place (see `resetGpuDeviceForTests`); never
|
|
29
|
+
* reassign the cell itself, or copies holding the old object diverge from the
|
|
30
|
+
* new one.
|
|
30
31
|
*/
|
|
31
32
|
const cell = (globalThis.__jbrowseRenderCoreGpuDeviceV1 ??= {
|
|
32
33
|
device: null,
|
|
@@ -90,8 +91,15 @@ function logGpuCapabilities(adapter, device) {
|
|
|
90
91
|
console.warn(`[GPU] WebGPU device ready — vendor="${vendor}" architecture="${architecture}" description="${description}" ` +
|
|
91
92
|
`maxTextureDimension2D=${maxTextureDimension2D} maxBufferSize=${maxBufferSize} maxStorageBufferBindingSize=${maxStorageBufferBindingSize}`);
|
|
92
93
|
}
|
|
94
|
+
/** The page's first adapter request; see `GpuDeviceCell.firstAdapter` */
|
|
95
|
+
export function requestFirstAdapter() {
|
|
96
|
+
cell.firstAdapter ??= navigator.gpu.requestAdapter();
|
|
97
|
+
return cell.firstAdapter;
|
|
98
|
+
}
|
|
93
99
|
async function acquire() {
|
|
94
|
-
const adapter = await
|
|
100
|
+
const adapter = await (cell.hadDevice
|
|
101
|
+
? navigator.gpu.requestAdapter()
|
|
102
|
+
: requestFirstAdapter());
|
|
95
103
|
if (!adapter) {
|
|
96
104
|
console.warn('[GPU] No compatible GPU adapter available. This may indicate WebGPU is disabled, unsupported hardware, or a system limitation. Falling back to WebGL2.');
|
|
97
105
|
return null;
|
|
@@ -152,8 +160,11 @@ async function createDevice() {
|
|
|
152
160
|
// Surface any WebGPU validation / out-of-memory / internal errors that
|
|
153
161
|
// would otherwise be silently swallowed. Without this, a bad draw/pipeline
|
|
154
162
|
// results in a blank canvas with no console output.
|
|
163
|
+
// The constructor name, because the message alone does not say whether a
|
|
164
|
+
// failure is validation, out-of-memory or internal — and that is what
|
|
165
|
+
// decides which `pushErrorScope` filter could have caught it.
|
|
155
166
|
d.addEventListener('uncapturederror', (event) => {
|
|
156
|
-
console.error(
|
|
167
|
+
console.error(`[GPU] UNCAPTURED ${event.error.constructor.name}:`, event.error.message);
|
|
157
168
|
});
|
|
158
169
|
void d.lost.then(info => {
|
|
159
170
|
// Identity check: if the shared device has already been replaced (test
|
|
@@ -183,10 +194,10 @@ async function createDevice() {
|
|
|
183
194
|
* The renderers `?renderer=` can pin the page to. `canvas` is a spelling of
|
|
184
195
|
* `canvas2d` kept because it is in the wild.
|
|
185
196
|
*
|
|
186
|
-
* A pin means *only* that rung — `createGpuHal` does not fall past it.
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
197
|
+
* A pin means *only* that rung — `createGpuHal` does not fall past it. The flag
|
|
198
|
+
* is for comparing backends, and a comparison that renders with a different
|
|
199
|
+
* backend than the one pinned is worse than no comparison. The failure shows
|
|
200
|
+
* instead, as a `renderError` carrying the pin that could
|
|
190
201
|
* not be honored, with the banner's "disable GPU" as the way out.
|
|
191
202
|
*/
|
|
192
203
|
export const GPU_OVERRIDES = ['webgpu', 'webgl', 'canvas2d', 'canvas'];
|
|
@@ -202,8 +213,8 @@ function isGpuOverride(value) {
|
|
|
202
213
|
* `--renderer` flag), so validating here is validating once at the only place
|
|
203
214
|
* an unchecked value enters. An unrecognized one clears the pin and says so:
|
|
204
215
|
* before this, `?renderer=WebGL` or a typo was indistinguishable from passing
|
|
205
|
-
* nothing at all,
|
|
206
|
-
*
|
|
216
|
+
* nothing at all, and a person debugging a renderer got the default ladder
|
|
217
|
+
* with no sign the pin was ignored.
|
|
207
218
|
*/
|
|
208
219
|
export function setGpuOverride(value) {
|
|
209
220
|
if (value !== null && !isGpuOverride(value)) {
|
|
@@ -216,6 +227,12 @@ export function setGpuOverride(value) {
|
|
|
216
227
|
export function getGpuOverride() {
|
|
217
228
|
return cell.gpuOverride;
|
|
218
229
|
}
|
|
230
|
+
export function setBuiltRenderer(name) {
|
|
231
|
+
cell.builtRenderer = name;
|
|
232
|
+
}
|
|
233
|
+
export function getBuiltRenderer() {
|
|
234
|
+
return cell.builtRenderer;
|
|
235
|
+
}
|
|
219
236
|
/**
|
|
220
237
|
* Whether the GPU is off for the whole page — either pinned by `?renderer=` at
|
|
221
238
|
* startup or switched off from a display's GPU-error banner after an
|
|
@@ -247,7 +264,9 @@ export function resetGpuDeviceForTests() {
|
|
|
247
264
|
cell.device = null;
|
|
248
265
|
cell.devicePromise = null;
|
|
249
266
|
cell.hadDevice = false;
|
|
267
|
+
cell.firstAdapter = undefined;
|
|
250
268
|
cell.deviceLostListeners.clear();
|
|
269
|
+
cell.builtRenderer = undefined;
|
|
251
270
|
}
|
|
252
271
|
export function getGpuDevice() {
|
|
253
272
|
const override = getGpuOverride();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export interface GraphicsCapabilities {
|
|
2
2
|
webgpu: boolean;
|
|
3
3
|
/**
|
|
4
|
-
* `undefined` when the WebGL2 probe was skipped
|
|
5
|
-
*
|
|
4
|
+
* `undefined` when the WebGL2 probe was skipped. `getGraphicsCapabilities`
|
|
5
|
+
* skips it whenever WebGPU answered first — see there.
|
|
6
6
|
*/
|
|
7
7
|
webgl2?: boolean;
|
|
8
8
|
gpuVendor?: string;
|
|
@@ -29,8 +29,8 @@ export interface GraphicsCapabilities {
|
|
|
29
29
|
* The rungs of the rendering ladder, as the names a person reads — the About
|
|
30
30
|
* widget's "Graphics:" line, the stack-trace dialog, the analytics field.
|
|
31
31
|
*
|
|
32
|
-
* Deliberately *not* the {@link GpuOverride} vocabulary,
|
|
33
|
-
* types into `?renderer
|
|
32
|
+
* Deliberately *not* the {@link GpuOverride} vocabulary, the values a user
|
|
33
|
+
* types into `?renderer=`, which therefore carry lowercase spellings and the
|
|
34
34
|
* `webgl`/`canvas` aliases. One is an input to parse, the other an answer to
|
|
35
35
|
* display, and collapsing them would mean either showing "canvas2d" in the UI
|
|
36
36
|
* or accepting "Canvas2D" in a URL.
|
|
@@ -65,22 +65,30 @@ export declare function isSoftwareRenderer(glRenderer: string): boolean;
|
|
|
65
65
|
*/
|
|
66
66
|
export declare function getGraphicsCapabilities(): Promise<GraphicsCapabilities>;
|
|
67
67
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
* Take the renderer ladder's device and capability steps now, before a display
|
|
69
|
+
* asks. On a real GPU the adapter and device requests took half a second, and a
|
|
70
|
+
* first display that starts them on mount paints that much after its data.
|
|
71
|
+
*/
|
|
72
|
+
export declare function prewarmGraphics(): void;
|
|
73
|
+
/**
|
|
74
|
+
* Which rung draws. Once `createGpuHal` has built one on this page, the rung it
|
|
75
|
+
* returned is the answer — the adapter probe says WebGPU where
|
|
76
|
+
* `WebGPUHal.create` then throws and the ladder lands on WebGL2. Before any
|
|
77
|
+
* backend exists it is the ladder read as an answer rather than run, from what
|
|
78
|
+
* the machine can do *and* the page-wide pin from `?renderer=` or the
|
|
79
|
+
* GPU-error banner's "disable GPU" button. This is the question every consumer
|
|
80
|
+
* asks: the About widget's "Graphics:" line, the stack-trace dialog's
|
|
81
|
+
* environment block, the analytics field.
|
|
74
82
|
*
|
|
75
|
-
* The pin is checked
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* that
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* machine, where the WebGL2 probe was skipped)
|
|
83
|
-
* decides on its own.
|
|
83
|
+
* The Canvas2D pin is checked ahead of the record because the banner's
|
|
84
|
+
* "disable GPU" sets it before the displays rebuild on the new rung. The other
|
|
85
|
+
* pins win outright in the prediction, because **a pin never falls through to
|
|
86
|
+
* the next rung** — `createGpuHal` throws instead, because a pinned renderer
|
|
87
|
+
* that falls back to another rung makes any comparison against it wrong. So the pinned rung *is* the answer, and a pin that cannot
|
|
88
|
+
* be honored surfaces as a `renderError` rather than as a different string
|
|
89
|
+
* here. The one case the prediction cannot resolve from capabilities alone
|
|
90
|
+
* (`?renderer=webgl` on a WebGPU machine, where the WebGL2 probe was skipped)
|
|
91
|
+
* is also the case where the pin decides on its own.
|
|
84
92
|
*
|
|
85
93
|
* **`softwareWebgl` skips the WebGL2 rung here because it skips it there**, and
|
|
86
94
|
* only where the ladder skips it — unpinned. Leaving it out is not a rounding
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getGpuOverride, isGpuRenderingDisabled } from './gpuDevice.js';
|
|
1
|
+
import { getBuiltRenderer, getGpuDevice, getGpuOverride, isGpuRenderingDisabled, requestFirstAdapter, } from './gpuDevice.js';
|
|
2
2
|
// Substrings of UNMASKED_RENDERER_WEBGL that mean "no GPU is involved". Kept
|
|
3
3
|
// conservative and specific — a wrong `true` here would describe a real GPU as
|
|
4
4
|
// software, and the reports built from it are what a later ladder decision would
|
|
@@ -28,7 +28,7 @@ async function probeWebgpu() {
|
|
|
28
28
|
try {
|
|
29
29
|
// navigator.gpu is typed non-nullable but is undefined without WebGPU
|
|
30
30
|
// support, so the try/catch guards that access as well as adapter failures
|
|
31
|
-
const adapter = await
|
|
31
|
+
const adapter = await requestFirstAdapter();
|
|
32
32
|
return adapter
|
|
33
33
|
? {
|
|
34
34
|
webgpu: true,
|
|
@@ -50,11 +50,11 @@ async function probeWebgpu() {
|
|
|
50
50
|
* that call is effectively driver-wide (ADR-005 removed it from
|
|
51
51
|
* `WebGL2Hal.dispose()` for the same reason), so probing while tracks were on
|
|
52
52
|
* screen knocked out their live sibling contexts — and both browsers log the
|
|
53
|
-
* loss to the console,
|
|
53
|
+
* loss to the console, where a user sees it. The canvas is unreachable the
|
|
54
54
|
* moment this returns and the browser reclaims the context on GC, the same
|
|
55
55
|
* release the HAL relies on. A page that then reaches the 16-context ceiling
|
|
56
56
|
* evicts this one first (it is the oldest, and nothing draws to it or
|
|
57
|
-
* re-acquires it), so the eviction cascade in
|
|
57
|
+
* re-acquires it), so the eviction cascade in GPU_PORTABILITY.md cannot
|
|
58
58
|
* start here.
|
|
59
59
|
*
|
|
60
60
|
* The driver string comes off the same context, so it is free where it matters:
|
|
@@ -111,22 +111,40 @@ export function getGraphicsCapabilities() {
|
|
|
111
111
|
return capabilities;
|
|
112
112
|
}
|
|
113
113
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
114
|
+
* Take the renderer ladder's device and capability steps now, before a display
|
|
115
|
+
* asks. On a real GPU the adapter and device requests took half a second, and a
|
|
116
|
+
* first display that starts them on mount paints that much after its data.
|
|
117
|
+
*/
|
|
118
|
+
export function prewarmGraphics() {
|
|
119
|
+
if (isGpuRenderingDisabled()) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const override = getGpuOverride();
|
|
123
|
+
void getGpuDevice().then(device => {
|
|
124
|
+
if (!device && override === null) {
|
|
125
|
+
void getGraphicsCapabilities();
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Which rung draws. Once `createGpuHal` has built one on this page, the rung it
|
|
131
|
+
* returned is the answer — the adapter probe says WebGPU where
|
|
132
|
+
* `WebGPUHal.create` then throws and the ladder lands on WebGL2. Before any
|
|
133
|
+
* backend exists it is the ladder read as an answer rather than run, from what
|
|
134
|
+
* the machine can do *and* the page-wide pin from `?renderer=` or the
|
|
135
|
+
* GPU-error banner's "disable GPU" button. This is the question every consumer
|
|
136
|
+
* asks: the About widget's "Graphics:" line, the stack-trace dialog's
|
|
137
|
+
* environment block, the analytics field.
|
|
120
138
|
*
|
|
121
|
-
* The pin is checked
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* that
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* machine, where the WebGL2 probe was skipped)
|
|
129
|
-
* decides on its own.
|
|
139
|
+
* The Canvas2D pin is checked ahead of the record because the banner's
|
|
140
|
+
* "disable GPU" sets it before the displays rebuild on the new rung. The other
|
|
141
|
+
* pins win outright in the prediction, because **a pin never falls through to
|
|
142
|
+
* the next rung** — `createGpuHal` throws instead, because a pinned renderer
|
|
143
|
+
* that falls back to another rung makes any comparison against it wrong. So the pinned rung *is* the answer, and a pin that cannot
|
|
144
|
+
* be honored surfaces as a `renderError` rather than as a different string
|
|
145
|
+
* here. The one case the prediction cannot resolve from capabilities alone
|
|
146
|
+
* (`?renderer=webgl` on a WebGPU machine, where the WebGL2 probe was skipped)
|
|
147
|
+
* is also the case where the pin decides on its own.
|
|
130
148
|
*
|
|
131
149
|
* **`softwareWebgl` skips the WebGL2 rung here because it skips it there**, and
|
|
132
150
|
* only where the ladder skips it — unpinned. Leaving it out is not a rounding
|
|
@@ -145,6 +163,10 @@ export function effectiveRenderer(c) {
|
|
|
145
163
|
if (isGpuRenderingDisabled()) {
|
|
146
164
|
return 'Canvas2D';
|
|
147
165
|
}
|
|
166
|
+
const built = getBuiltRenderer();
|
|
167
|
+
if (built) {
|
|
168
|
+
return built;
|
|
169
|
+
}
|
|
148
170
|
const override = getGpuOverride();
|
|
149
171
|
if (override === 'webgl') {
|
|
150
172
|
return 'WebGL2';
|
package/esm/hal/createHal.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type { GpuHal, PipelineDescriptor, SampleCount } from './types.ts';
|
|
2
2
|
export interface GpuHalOptions {
|
|
3
3
|
passes: PipelineDescriptor[];
|
|
4
|
-
uniformByteSize: number;
|
|
5
4
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* own
|
|
5
|
+
* WebGPU sizes its multisampled target by it; WebGL2 asks the browser for an
|
|
6
|
+
* antialiased drawing buffer only above one sample, so a display whose passes
|
|
7
|
+
* all measure their own coverage pays for no samples on either rung.
|
|
9
8
|
*/
|
|
10
9
|
sampleCount: SampleCount;
|
|
11
10
|
/**
|
|
@@ -19,4 +18,4 @@ export interface GpuHalOptions {
|
|
|
19
18
|
*/
|
|
20
19
|
failures?: unknown[];
|
|
21
20
|
}
|
|
22
|
-
export declare function createGpuHal(canvas: HTMLCanvasElement,
|
|
21
|
+
export declare function createGpuHal(canvas: HTMLCanvasElement, options: GpuHalOptions): Promise<GpuHal | null>;
|
package/esm/hal/createHal.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getGpuOverride, isGpuRenderingDisabled } from '../gpuDevice.js';
|
|
1
|
+
import { getGpuOverride, isGpuRenderingDisabled, setBuiltRenderer, } from '../gpuDevice.js';
|
|
2
2
|
import { getGraphicsCapabilities } from '../graphicsCapabilities.js';
|
|
3
3
|
import { WebGL2Hal } from './webgl2Hal.js';
|
|
4
4
|
import { WebGPUHal } from './webgpuHal.js';
|
|
@@ -17,14 +17,24 @@ function warnSoftwareRasterizerOnce(glRenderer) {
|
|
|
17
17
|
// Ladder: WebGPU → WebGL2 → Canvas2D (null). The `?renderer=` URL param pins it
|
|
18
18
|
// to a single rung for debugging — `webgpu`, `webgl`, or `canvas2d`/`canvas` —
|
|
19
19
|
// and a pin never falls through to the next rung. See GPU_OVERRIDES.
|
|
20
|
-
|
|
20
|
+
//
|
|
21
|
+
// Records the rung it returned on the page-wide cell, which is how
|
|
22
|
+
// `effectiveRenderer` gets to report what drew rather than what the adapter
|
|
23
|
+
// probe predicted — the two part when `WebGPUHal.create` throws and the ladder
|
|
24
|
+
// lands on WebGL2.
|
|
25
|
+
export async function createGpuHal(canvas, options) {
|
|
26
|
+
const hal = await climbLadder(canvas, options);
|
|
27
|
+
setBuiltRenderer(hal === null ? 'Canvas2D' : hal instanceof WebGPUHal ? 'WebGPU' : 'WebGL2');
|
|
28
|
+
return hal;
|
|
29
|
+
}
|
|
30
|
+
async function climbLadder(canvas, { passes, sampleCount, failures }) {
|
|
21
31
|
if (isGpuRenderingDisabled()) {
|
|
22
32
|
return null;
|
|
23
33
|
}
|
|
24
34
|
const override = getGpuOverride();
|
|
25
35
|
if (override !== 'webgl') {
|
|
26
36
|
try {
|
|
27
|
-
const webgpu = await WebGPUHal.create(canvas, passes,
|
|
37
|
+
const webgpu = await WebGPUHal.create(canvas, passes, sampleCount);
|
|
28
38
|
if (webgpu) {
|
|
29
39
|
return webgpu;
|
|
30
40
|
}
|
|
@@ -54,7 +64,7 @@ export async function createGpuHal(canvas, { passes, uniformByteSize, sampleCoun
|
|
|
54
64
|
// volvox tracks, and *no scroll churn at all* — headless Chrome (SwiftShader),
|
|
55
65
|
// three runs each: WebGL2 blocks the main thread for 1.3-5.5 s in a single
|
|
56
66
|
// task and 2.1-8.8 s in total, while Canvas2D never exceeds 339 ms and never
|
|
57
|
-
// once produces a task over 500 ms.
|
|
67
|
+
// once produces a task over 500 ms. GPU_PORTABILITY.md has the churn case
|
|
58
68
|
// at ~25x; this is the floor, and it is the load-time pipeline build rather
|
|
59
69
|
// than the per-pass rebuild the churn number measures.
|
|
60
70
|
//
|
|
@@ -81,7 +91,7 @@ export async function createGpuHal(canvas, { passes, uniformByteSize, sampleCoun
|
|
|
81
91
|
}
|
|
82
92
|
}
|
|
83
93
|
try {
|
|
84
|
-
return
|
|
94
|
+
return await WebGL2Hal.create(canvas, passes, sampleCount);
|
|
85
95
|
}
|
|
86
96
|
catch (e) {
|
|
87
97
|
console.warn('[GPU] WebGL2 unavailable, falling back to Canvas2D:', e);
|
|
@@ -1,36 +1,31 @@
|
|
|
1
|
-
import type { PipelineDescriptor, SampleCount } from './types.ts';
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* not worth the null-bundling for two objects per *device*.
|
|
7
|
-
*/
|
|
8
|
-
export interface DeviceLayouts {
|
|
9
|
-
uniformOnlyBindGroupLayout: GPUBindGroupLayout;
|
|
10
|
-
uniformOnlyPipelineLayout: GPUPipelineLayout;
|
|
11
|
-
texturedBindGroupLayout: GPUBindGroupLayout;
|
|
12
|
-
texturedPipelineLayout: GPUPipelineLayout;
|
|
1
|
+
import type { PipelineDescriptor, SampleCount, ShaderBinding } from './types.ts';
|
|
2
|
+
/** A pass's one bind-group layout, and the pipeline layout holding it as group 0. */
|
|
3
|
+
export interface PassLayout {
|
|
4
|
+
bindGroupLayout: GPUBindGroupLayout;
|
|
5
|
+
pipelineLayout: GPUPipelineLayout;
|
|
13
6
|
}
|
|
14
7
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* new object, so the layouts and pipelines built against the dead one are
|
|
20
|
-
* unreachable and there is no cache to invalidate by hand.
|
|
8
|
+
* A render pass's bind-group layout, read off its shader's reflected table:
|
|
9
|
+
* each binding visible to exactly the stages that read it, so the layout
|
|
10
|
+
* cannot disagree with the shader about which stage reads what. The uniform
|
|
11
|
+
* block takes a dynamic offset into the HAL's ring.
|
|
21
12
|
*/
|
|
22
|
-
export declare function
|
|
13
|
+
export declare function bindGroupLayoutEntries(bindings: readonly ShaderBinding[]): GPUBindGroupLayoutEntry[];
|
|
23
14
|
/**
|
|
24
|
-
*
|
|
25
|
-
* `
|
|
26
|
-
*
|
|
27
|
-
* `build` receives the sample count rather than closing over one, so the key
|
|
28
|
-
* and the pipeline stored under it cannot disagree.
|
|
29
|
-
*/
|
|
30
|
-
export declare function getOrBuildPipeline(device: GPUDevice, desc: PipelineDescriptor, sampleCount: SampleCount, build: (layouts: DeviceLayouts, sampleCount: SampleCount) => Promise<GPURenderPipeline>): Promise<GPURenderPipeline>;
|
|
31
|
-
/**
|
|
32
|
-
* Drop every device's entry. Tests only — nothing in the app invalidates this
|
|
33
|
-
* cache, because losing the device is what invalidates it (see
|
|
34
|
-
* {@link getDeviceLayouts}).
|
|
15
|
+
* What a pipeline is compiled from and cached under: `WebGPUHal` builds from
|
|
16
|
+
* nothing else. `uniformByteSize` stays out, since the layouts declare no
|
|
17
|
+
* `minBindingSize`, and so does the page-wide canvas format.
|
|
35
18
|
*/
|
|
19
|
+
export interface PipelineRecipe {
|
|
20
|
+
wgslSource: string;
|
|
21
|
+
bindGroupLayout: GPUBindGroupLayoutEntry[];
|
|
22
|
+
vertexBuffer: GPUVertexBufferLayout;
|
|
23
|
+
blend: GPUBlendState | undefined;
|
|
24
|
+
topology: GPUPrimitiveTopology;
|
|
25
|
+
/** Baked in: a pipeline built at 4 draws nothing into a target at 1. */
|
|
26
|
+
sampleCount: SampleCount;
|
|
27
|
+
}
|
|
28
|
+
export declare function pipelineRecipe(desc: PipelineDescriptor, wgslSource: string, sampleCount: SampleCount): PipelineRecipe;
|
|
29
|
+
export declare function getPassLayout(device: GPUDevice, entries: GPUBindGroupLayoutEntry[]): PassLayout;
|
|
30
|
+
export declare function getOrBuildPipeline(device: GPUDevice, recipe: PipelineRecipe, build: (recipe: PipelineRecipe) => Promise<GPURenderPipeline>): Promise<GPURenderPipeline>;
|
|
36
31
|
export declare function resetDeviceGpuCacheForTests(device: GPUDevice): void;
|