@luma.gl/core 9.2.5 → 9.3.0-alpha.10
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/dist/adapter/canvas-context.d.ts +6 -162
- package/dist/adapter/canvas-context.d.ts.map +1 -1
- package/dist/adapter/canvas-context.js +5 -419
- package/dist/adapter/canvas-context.js.map +1 -1
- package/dist/adapter/canvas-observer.d.ts +32 -0
- package/dist/adapter/canvas-observer.d.ts.map +1 -0
- package/dist/adapter/canvas-observer.js +90 -0
- package/dist/adapter/canvas-observer.js.map +1 -0
- package/dist/adapter/canvas-surface.d.ts +150 -0
- package/dist/adapter/canvas-surface.d.ts.map +1 -0
- package/dist/adapter/canvas-surface.js +392 -0
- package/dist/adapter/canvas-surface.js.map +1 -0
- package/dist/adapter/device.d.ts +81 -16
- package/dist/adapter/device.d.ts.map +1 -1
- package/dist/adapter/device.js +196 -10
- package/dist/adapter/device.js.map +1 -1
- package/dist/adapter/luma.js +1 -1
- package/dist/adapter/luma.js.map +1 -1
- package/dist/adapter/presentation-context.d.ts +11 -0
- package/dist/adapter/presentation-context.d.ts.map +1 -0
- package/dist/adapter/presentation-context.js +12 -0
- package/dist/adapter/presentation-context.js.map +1 -0
- package/dist/adapter/resources/buffer.d.ts +5 -5
- package/dist/adapter/resources/buffer.d.ts.map +1 -1
- package/dist/adapter/resources/buffer.js +18 -7
- package/dist/adapter/resources/buffer.js.map +1 -1
- package/dist/adapter/resources/command-buffer.d.ts +3 -1
- package/dist/adapter/resources/command-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/command-buffer.js +3 -1
- package/dist/adapter/resources/command-buffer.js.map +1 -1
- package/dist/adapter/resources/command-encoder.d.ts +30 -7
- package/dist/adapter/resources/command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/command-encoder.js +68 -2
- package/dist/adapter/resources/command-encoder.js.map +1 -1
- package/dist/adapter/resources/compute-pipeline.d.ts +2 -2
- package/dist/adapter/resources/compute-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/fence.d.ts +16 -0
- package/dist/adapter/resources/fence.d.ts.map +1 -0
- package/dist/adapter/resources/fence.js +17 -0
- package/dist/adapter/resources/fence.js.map +1 -0
- package/dist/adapter/resources/framebuffer.d.ts +1 -1
- package/dist/adapter/resources/framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/framebuffer.js +15 -12
- package/dist/adapter/resources/framebuffer.js.map +1 -1
- package/dist/adapter/resources/query-set.d.ts +17 -1
- package/dist/adapter/resources/query-set.d.ts.map +1 -1
- package/dist/adapter/resources/query-set.js.map +1 -1
- package/dist/adapter/resources/render-pipeline.d.ts +28 -10
- package/dist/adapter/resources/render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/render-pipeline.js +21 -2
- package/dist/adapter/resources/render-pipeline.js.map +1 -1
- package/dist/adapter/resources/resource.d.ts +13 -0
- package/dist/adapter/resources/resource.d.ts.map +1 -1
- package/dist/adapter/resources/resource.js +243 -14
- package/dist/adapter/resources/resource.js.map +1 -1
- package/dist/adapter/resources/shader.js +27 -25
- package/dist/adapter/resources/shader.js.map +1 -1
- package/dist/adapter/resources/shared-render-pipeline.d.ts +22 -0
- package/dist/adapter/resources/shared-render-pipeline.d.ts.map +1 -0
- package/dist/adapter/resources/shared-render-pipeline.js +25 -0
- package/dist/adapter/resources/shared-render-pipeline.js.map +1 -0
- package/dist/adapter/resources/texture-view.d.ts +1 -1
- package/dist/adapter/resources/texture-view.d.ts.map +1 -1
- package/dist/adapter/resources/texture.d.ts +168 -28
- package/dist/adapter/resources/texture.d.ts.map +1 -1
- package/dist/adapter/resources/texture.js +284 -25
- package/dist/adapter/resources/texture.js.map +1 -1
- package/dist/adapter/types/attachments.d.ts +1 -1
- package/dist/adapter/types/attachments.d.ts.map +1 -1
- package/dist/adapter/types/buffer-layout.d.ts +1 -1
- package/dist/adapter/types/buffer-layout.d.ts.map +1 -1
- package/dist/adapter/types/parameters.d.ts +3 -1
- package/dist/adapter/types/parameters.d.ts.map +1 -1
- package/dist/adapter/types/parameters.js +1 -0
- package/dist/adapter/types/parameters.js.map +1 -1
- package/dist/adapter/types/shader-layout.d.ts +10 -6
- package/dist/adapter/types/shader-layout.d.ts.map +1 -1
- package/dist/adapter/types/uniforms.d.ts +6 -0
- package/dist/adapter/types/uniforms.d.ts.map +1 -1
- package/dist/adapter-utils/bind-groups.d.ts +9 -0
- package/dist/adapter-utils/bind-groups.d.ts.map +1 -0
- package/dist/adapter-utils/bind-groups.js +41 -0
- package/dist/adapter-utils/bind-groups.js.map +1 -0
- package/dist/adapter-utils/format-compiler-log.d.ts.map +1 -1
- package/dist/adapter-utils/format-compiler-log.js +23 -15
- package/dist/adapter-utils/format-compiler-log.js.map +1 -1
- package/dist/adapter-utils/get-attribute-from-layouts.d.ts +2 -2
- package/dist/adapter-utils/get-attribute-from-layouts.d.ts.map +1 -1
- package/dist/adapter-utils/get-attribute-from-layouts.js +6 -6
- package/dist/adapter-utils/get-attribute-from-layouts.js.map +1 -1
- package/dist/dist.dev.js +2692 -645
- package/dist/dist.min.js +10 -9
- package/dist/factories/bind-group-factory.d.ts +20 -0
- package/dist/factories/bind-group-factory.d.ts.map +1 -0
- package/dist/factories/bind-group-factory.js +79 -0
- package/dist/factories/bind-group-factory.js.map +1 -0
- package/dist/factories/core-module-state.d.ts +7 -0
- package/dist/factories/core-module-state.d.ts.map +1 -0
- package/dist/{shadertypes/data-types/shader-types.js → factories/core-module-state.js} +1 -1
- package/dist/factories/core-module-state.js.map +1 -0
- package/dist/factories/pipeline-factory.d.ts +54 -0
- package/dist/factories/pipeline-factory.d.ts.map +1 -0
- package/dist/factories/pipeline-factory.js +270 -0
- package/dist/factories/pipeline-factory.js.map +1 -0
- package/dist/factories/shader-factory.d.ts +20 -0
- package/dist/factories/shader-factory.d.ts.map +1 -0
- package/dist/factories/shader-factory.js +84 -0
- package/dist/factories/shader-factory.js.map +1 -0
- package/dist/index.cjs +2427 -554
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +30 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/portable/shader-block-writer.d.ts +51 -0
- package/dist/portable/shader-block-writer.d.ts.map +1 -0
- package/dist/portable/shader-block-writer.js +185 -0
- package/dist/portable/shader-block-writer.js.map +1 -0
- package/dist/portable/uniform-block.d.ts +1 -1
- package/dist/portable/uniform-block.d.ts.map +1 -1
- package/dist/portable/uniform-store.d.ts +55 -24
- package/dist/portable/uniform-store.d.ts.map +1 -1
- package/dist/portable/uniform-store.js +73 -25
- package/dist/portable/uniform-store.js.map +1 -1
- package/dist/shadertypes/data-types/data-type-decoder.d.ts +20 -0
- package/dist/shadertypes/data-types/data-type-decoder.d.ts.map +1 -0
- package/dist/shadertypes/data-types/data-type-decoder.js +79 -0
- package/dist/shadertypes/data-types/data-type-decoder.js.map +1 -0
- package/dist/shadertypes/data-types/data-types.d.ts +31 -12
- package/dist/shadertypes/data-types/data-types.d.ts.map +1 -1
- package/dist/shadertypes/data-types/decode-data-types.d.ts.map +1 -1
- package/dist/shadertypes/data-types/decode-data-types.js +2 -1
- package/dist/shadertypes/data-types/decode-data-types.js.map +1 -1
- package/dist/{image-utils → shadertypes/image-types}/image-types.d.ts +0 -6
- package/dist/shadertypes/image-types/image-types.d.ts.map +1 -0
- package/dist/shadertypes/image-types/image-types.js.map +1 -0
- package/dist/shadertypes/shader-types/shader-block-layout.d.ts +72 -0
- package/dist/shadertypes/shader-types/shader-block-layout.d.ts.map +1 -0
- package/dist/shadertypes/shader-types/shader-block-layout.js +209 -0
- package/dist/shadertypes/shader-types/shader-block-layout.js.map +1 -0
- package/dist/shadertypes/shader-types/shader-type-decoder.d.ts +41 -0
- package/dist/shadertypes/shader-types/shader-type-decoder.d.ts.map +1 -0
- package/dist/shadertypes/{data-types/decode-shader-types.js → shader-types/shader-type-decoder.js} +43 -4
- package/dist/shadertypes/shader-types/shader-type-decoder.js.map +1 -0
- package/dist/shadertypes/shader-types/shader-types.d.ts +101 -0
- package/dist/shadertypes/shader-types/shader-types.d.ts.map +1 -0
- package/dist/shadertypes/shader-types/shader-types.js +30 -0
- package/dist/shadertypes/shader-types/shader-types.js.map +1 -0
- package/dist/shadertypes/texture-types/pixel-utils.d.ts.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/pixel-utils.js +4 -4
- package/dist/shadertypes/texture-types/pixel-utils.js.map +1 -0
- package/dist/shadertypes/texture-types/texture-format-decoder.d.ts +36 -0
- package/dist/shadertypes/texture-types/texture-format-decoder.d.ts.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/texture-format-decoder.js +109 -37
- package/dist/shadertypes/texture-types/texture-format-decoder.js.map +1 -0
- package/dist/shadertypes/texture-types/texture-format-generics.d.ts +34 -0
- package/dist/shadertypes/texture-types/texture-format-generics.d.ts.map +1 -0
- package/dist/shadertypes/texture-types/texture-format-generics.js.map +1 -0
- package/dist/shadertypes/texture-types/texture-format-table.d.ts.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/texture-format-table.js +10 -9
- package/dist/shadertypes/texture-types/texture-format-table.js.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/texture-formats.d.ts +51 -17
- package/dist/shadertypes/texture-types/texture-formats.d.ts.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/texture-formats.js +1 -0
- package/dist/shadertypes/texture-types/texture-formats.js.map +1 -0
- package/dist/shadertypes/texture-types/texture-layout.d.ts +5 -0
- package/dist/shadertypes/texture-types/texture-layout.d.ts.map +1 -0
- package/dist/shadertypes/texture-types/texture-layout.js +41 -0
- package/dist/shadertypes/texture-types/texture-layout.js.map +1 -0
- package/dist/shadertypes/vertex-types/vertex-format-decoder.d.ts +24 -0
- package/dist/shadertypes/vertex-types/vertex-format-decoder.d.ts.map +1 -0
- package/dist/shadertypes/vertex-types/vertex-format-decoder.js +106 -0
- package/dist/shadertypes/vertex-types/vertex-format-decoder.js.map +1 -0
- package/dist/shadertypes/vertex-types/vertex-formats.d.ts +50 -0
- package/dist/shadertypes/vertex-types/vertex-formats.d.ts.map +1 -0
- package/dist/shadertypes/vertex-types/vertex-formats.js.map +1 -0
- package/dist/utils/array-equal.d.ts +1 -1
- package/dist/utils/array-equal.d.ts.map +1 -1
- package/dist/utils/array-equal.js +15 -9
- package/dist/utils/array-equal.js.map +1 -1
- package/dist/utils/assert.d.ts +5 -0
- package/dist/utils/assert.d.ts.map +1 -0
- package/dist/utils/assert.js +17 -0
- package/dist/utils/assert.js.map +1 -0
- package/dist/utils/stats-manager.d.ts.map +1 -1
- package/dist/utils/stats-manager.js +61 -1
- package/dist/utils/stats-manager.js.map +1 -1
- package/package.json +6 -6
- package/src/adapter/canvas-context.ts +7 -556
- package/src/adapter/canvas-observer.ts +130 -0
- package/src/adapter/canvas-surface.ts +521 -0
- package/src/adapter/device.ts +312 -24
- package/src/adapter/presentation-context.ts +16 -0
- package/src/adapter/resources/buffer.ts +19 -9
- package/src/adapter/resources/command-buffer.ts +4 -2
- package/src/adapter/resources/command-encoder.ts +101 -10
- package/src/adapter/resources/compute-pipeline.ts +2 -2
- package/src/adapter/resources/fence.ts +32 -0
- package/src/adapter/resources/framebuffer.ts +16 -13
- package/src/adapter/resources/query-set.ts +17 -1
- package/src/adapter/resources/render-pipeline.ts +52 -16
- package/src/adapter/resources/resource.ts +289 -14
- package/src/adapter/resources/shader.ts +28 -28
- package/src/adapter/resources/shared-render-pipeline.ts +40 -0
- package/src/adapter/resources/texture-view.ts +1 -1
- package/src/adapter/resources/texture.ts +427 -49
- package/src/adapter/types/attachments.ts +1 -1
- package/src/adapter/types/buffer-layout.ts +1 -1
- package/src/adapter/types/parameters.ts +4 -1
- package/src/adapter/types/shader-layout.ts +15 -9
- package/src/adapter/types/uniforms.ts +12 -0
- package/src/adapter-utils/bind-groups.ts +71 -0
- package/src/adapter-utils/format-compiler-log.ts +23 -15
- package/src/adapter-utils/get-attribute-from-layouts.ts +8 -11
- package/src/factories/bind-group-factory.ts +139 -0
- package/src/factories/core-module-state.ts +11 -0
- package/src/factories/pipeline-factory.ts +328 -0
- package/src/factories/shader-factory.ts +103 -0
- package/src/index.ts +70 -26
- package/src/portable/shader-block-writer.ts +254 -0
- package/src/portable/uniform-block.ts +1 -1
- package/src/portable/uniform-store.ts +98 -40
- package/src/shadertypes/data-types/data-type-decoder.ts +105 -0
- package/src/shadertypes/data-types/data-types.ts +100 -48
- package/src/shadertypes/data-types/decode-data-types.ts +2 -1
- package/src/{image-utils → shadertypes/image-types}/image-types.ts +0 -7
- package/src/shadertypes/shader-types/shader-block-layout.ts +340 -0
- package/src/shadertypes/{data-types/decode-shader-types.ts → shader-types/shader-type-decoder.ts} +88 -14
- package/src/shadertypes/shader-types/shader-types.ts +207 -0
- package/src/shadertypes/{textures → texture-types}/pixel-utils.ts +4 -4
- package/src/shadertypes/{textures → texture-types}/texture-format-decoder.ts +166 -45
- package/src/shadertypes/{textures → texture-types}/texture-format-generics.ts +42 -48
- package/src/shadertypes/{textures → texture-types}/texture-format-table.ts +10 -9
- package/src/shadertypes/{textures → texture-types}/texture-formats.ts +73 -17
- package/src/shadertypes/texture-types/texture-layout.ts +60 -0
- package/src/shadertypes/vertex-types/vertex-format-decoder.ts +131 -0
- package/src/shadertypes/vertex-types/vertex-formats.ts +183 -0
- package/src/utils/array-equal.ts +21 -9
- package/src/utils/assert.ts +18 -0
- package/src/utils/stats-manager.ts +76 -2
- package/dist/image-utils/image-types.d.ts.map +0 -1
- package/dist/image-utils/image-types.js.map +0 -1
- package/dist/portable/uniform-buffer-layout.d.ts +0 -28
- package/dist/portable/uniform-buffer-layout.d.ts.map +0 -1
- package/dist/portable/uniform-buffer-layout.js +0 -96
- package/dist/portable/uniform-buffer-layout.js.map +0 -1
- package/dist/shadertypes/data-types/decode-shader-types.d.ts +0 -17
- package/dist/shadertypes/data-types/decode-shader-types.d.ts.map +0 -1
- package/dist/shadertypes/data-types/decode-shader-types.js.map +0 -1
- package/dist/shadertypes/data-types/shader-types.d.ts +0 -45
- package/dist/shadertypes/data-types/shader-types.d.ts.map +0 -1
- package/dist/shadertypes/data-types/shader-types.js.map +0 -1
- package/dist/shadertypes/textures/pixel-utils.d.ts.map +0 -1
- package/dist/shadertypes/textures/pixel-utils.js.map +0 -1
- package/dist/shadertypes/textures/texture-format-decoder.d.ts +0 -18
- package/dist/shadertypes/textures/texture-format-decoder.d.ts.map +0 -1
- package/dist/shadertypes/textures/texture-format-decoder.js.map +0 -1
- package/dist/shadertypes/textures/texture-format-generics.d.ts +0 -33
- package/dist/shadertypes/textures/texture-format-generics.d.ts.map +0 -1
- package/dist/shadertypes/textures/texture-format-generics.js.map +0 -1
- package/dist/shadertypes/textures/texture-format-table.d.ts.map +0 -1
- package/dist/shadertypes/textures/texture-format-table.js.map +0 -1
- package/dist/shadertypes/textures/texture-formats.d.ts.map +0 -1
- package/dist/shadertypes/textures/texture-formats.js.map +0 -1
- package/dist/shadertypes/vertex-arrays/decode-vertex-format.d.ts +0 -18
- package/dist/shadertypes/vertex-arrays/decode-vertex-format.d.ts.map +0 -1
- package/dist/shadertypes/vertex-arrays/decode-vertex-format.js +0 -100
- package/dist/shadertypes/vertex-arrays/decode-vertex-format.js.map +0 -1
- package/dist/shadertypes/vertex-arrays/vertex-formats.d.ts +0 -27
- package/dist/shadertypes/vertex-arrays/vertex-formats.d.ts.map +0 -1
- package/dist/shadertypes/vertex-arrays/vertex-formats.js.map +0 -1
- package/src/portable/uniform-buffer-layout.ts +0 -118
- package/src/shadertypes/data-types/shader-types.ts +0 -87
- package/src/shadertypes/vertex-arrays/decode-vertex-format.ts +0 -124
- package/src/shadertypes/vertex-arrays/vertex-formats.ts +0 -91
- /package/dist/{image-utils → shadertypes/image-types}/image-types.js +0 -0
- /package/dist/shadertypes/{textures → texture-types}/pixel-utils.d.ts +0 -0
- /package/dist/shadertypes/{textures → texture-types}/texture-format-generics.js +0 -0
- /package/dist/shadertypes/{textures → texture-types}/texture-format-table.d.ts +0 -0
- /package/dist/shadertypes/{vertex-arrays → vertex-types}/vertex-formats.js +0 -0
package/dist/index.cjs
CHANGED
|
@@ -36,45 +36,75 @@ __export(dist_exports, {
|
|
|
36
36
|
DeviceFeatures: () => DeviceFeatures,
|
|
37
37
|
DeviceLimits: () => DeviceLimits,
|
|
38
38
|
ExternalTexture: () => ExternalTexture,
|
|
39
|
+
Fence: () => Fence,
|
|
39
40
|
Framebuffer: () => Framebuffer,
|
|
41
|
+
PipelineFactory: () => PipelineFactory,
|
|
40
42
|
PipelineLayout: () => PipelineLayout,
|
|
43
|
+
PresentationContext: () => PresentationContext,
|
|
41
44
|
QuerySet: () => QuerySet,
|
|
42
45
|
RenderPass: () => RenderPass,
|
|
43
46
|
RenderPipeline: () => RenderPipeline,
|
|
44
47
|
Resource: () => Resource,
|
|
45
48
|
Sampler: () => Sampler,
|
|
46
49
|
Shader: () => Shader,
|
|
50
|
+
ShaderBlockWriter: () => ShaderBlockWriter,
|
|
51
|
+
ShaderFactory: () => ShaderFactory,
|
|
52
|
+
SharedRenderPipeline: () => SharedRenderPipeline,
|
|
47
53
|
Texture: () => Texture,
|
|
48
|
-
TextureFormatDecoder: () => TextureFormatDecoder,
|
|
49
54
|
TextureView: () => TextureView,
|
|
50
55
|
TransformFeedback: () => TransformFeedback,
|
|
51
56
|
UniformBlock: () => UniformBlock,
|
|
52
|
-
UniformBufferLayout: () => UniformBufferLayout,
|
|
53
57
|
UniformStore: () => UniformStore,
|
|
54
58
|
VertexArray: () => VertexArray,
|
|
59
|
+
_getDefaultBindGroupFactory: () => _getDefaultBindGroupFactory,
|
|
55
60
|
_getTextureFormatDefinition: () => getTextureFormatDefinition,
|
|
56
61
|
_getTextureFormatTable: () => getTextureFormatTable,
|
|
62
|
+
assert: () => assert,
|
|
63
|
+
assertDefined: () => assertDefined,
|
|
64
|
+
dataTypeDecoder: () => dataTypeDecoder,
|
|
65
|
+
flattenBindingsByGroup: () => flattenBindingsByGroup,
|
|
57
66
|
getAttributeInfosFromLayouts: () => getAttributeInfosFromLayouts,
|
|
58
67
|
getAttributeShaderTypeInfo: () => getAttributeShaderTypeInfo,
|
|
59
|
-
|
|
60
|
-
getDataTypeInfo: () => getDataTypeInfo,
|
|
61
|
-
getNormalizedDataType: () => getNormalizedDataType,
|
|
68
|
+
getExternalImageSize: () => getExternalImageSize,
|
|
62
69
|
getScratchArray: () => getScratchArray,
|
|
70
|
+
getShaderLayoutBinding: () => getShaderLayoutBinding,
|
|
71
|
+
getTextureImageView: () => getTextureImageView,
|
|
63
72
|
getTypedArrayConstructor: () => getTypedArrayConstructor,
|
|
64
73
|
getVariableShaderTypeInfo: () => getVariableShaderTypeInfo,
|
|
65
|
-
|
|
66
|
-
getVertexFormatInfo: () => getVertexFormatInfo,
|
|
74
|
+
isExternalImage: () => isExternalImage,
|
|
67
75
|
log: () => log,
|
|
68
76
|
luma: () => luma,
|
|
69
|
-
|
|
77
|
+
makeShaderBlockLayout: () => makeShaderBlockLayout,
|
|
78
|
+
normalizeBindingsByGroup: () => normalizeBindingsByGroup,
|
|
70
79
|
readPixel: () => readPixel,
|
|
80
|
+
setTextureImageData: () => setTextureImageData,
|
|
81
|
+
shaderTypeDecoder: () => shaderTypeDecoder,
|
|
71
82
|
textureFormatDecoder: () => textureFormatDecoder,
|
|
83
|
+
vertexFormatDecoder: () => vertexFormatDecoder,
|
|
72
84
|
writePixel: () => writePixel
|
|
73
85
|
});
|
|
74
86
|
module.exports = __toCommonJS(dist_exports);
|
|
75
87
|
|
|
76
88
|
// dist/utils/stats-manager.js
|
|
77
89
|
var import_stats = require("@probe.gl/stats");
|
|
90
|
+
var GPU_TIME_AND_MEMORY_STATS = "GPU Time and Memory";
|
|
91
|
+
var GPU_TIME_AND_MEMORY_STAT_ORDER = [
|
|
92
|
+
"Adapter",
|
|
93
|
+
"GPU",
|
|
94
|
+
"GPU Type",
|
|
95
|
+
"GPU Backend",
|
|
96
|
+
"Frame Rate",
|
|
97
|
+
"CPU Time",
|
|
98
|
+
"GPU Time",
|
|
99
|
+
"GPU Memory",
|
|
100
|
+
"Buffer Memory",
|
|
101
|
+
"Texture Memory",
|
|
102
|
+
"Referenced Buffer Memory",
|
|
103
|
+
"Referenced Texture Memory",
|
|
104
|
+
"Swap Chain Texture"
|
|
105
|
+
];
|
|
106
|
+
var ORDERED_STATS_CACHE = /* @__PURE__ */ new WeakMap();
|
|
107
|
+
var ORDERED_STAT_NAME_SET_CACHE = /* @__PURE__ */ new WeakMap();
|
|
78
108
|
var StatsManager = class {
|
|
79
109
|
stats = /* @__PURE__ */ new Map();
|
|
80
110
|
getStats(name2) {
|
|
@@ -84,10 +114,50 @@ var StatsManager = class {
|
|
|
84
114
|
if (!this.stats.has(name2)) {
|
|
85
115
|
this.stats.set(name2, new import_stats.Stats({ id: name2 }));
|
|
86
116
|
}
|
|
87
|
-
|
|
117
|
+
const stats = this.stats.get(name2);
|
|
118
|
+
if (name2 === GPU_TIME_AND_MEMORY_STATS) {
|
|
119
|
+
initializeStats(stats, GPU_TIME_AND_MEMORY_STAT_ORDER);
|
|
120
|
+
}
|
|
121
|
+
return stats;
|
|
88
122
|
}
|
|
89
123
|
};
|
|
90
124
|
var lumaStats = new StatsManager();
|
|
125
|
+
function initializeStats(stats, orderedStatNames) {
|
|
126
|
+
const statsMap = stats.stats;
|
|
127
|
+
let addedOrderedStat = false;
|
|
128
|
+
for (const statName of orderedStatNames) {
|
|
129
|
+
if (!statsMap[statName]) {
|
|
130
|
+
stats.get(statName);
|
|
131
|
+
addedOrderedStat = true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const statCount = Object.keys(statsMap).length;
|
|
135
|
+
const cachedStats = ORDERED_STATS_CACHE.get(stats);
|
|
136
|
+
if (!addedOrderedStat && (cachedStats == null ? void 0 : cachedStats.orderedStatNames) === orderedStatNames && cachedStats.statCount === statCount) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const reorderedStats = {};
|
|
140
|
+
let orderedStatNamesSet = ORDERED_STAT_NAME_SET_CACHE.get(orderedStatNames);
|
|
141
|
+
if (!orderedStatNamesSet) {
|
|
142
|
+
orderedStatNamesSet = new Set(orderedStatNames);
|
|
143
|
+
ORDERED_STAT_NAME_SET_CACHE.set(orderedStatNames, orderedStatNamesSet);
|
|
144
|
+
}
|
|
145
|
+
for (const statName of orderedStatNames) {
|
|
146
|
+
if (statsMap[statName]) {
|
|
147
|
+
reorderedStats[statName] = statsMap[statName];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
for (const [statName, stat] of Object.entries(statsMap)) {
|
|
151
|
+
if (!orderedStatNamesSet.has(statName)) {
|
|
152
|
+
reorderedStats[statName] = stat;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
for (const statName of Object.keys(statsMap)) {
|
|
156
|
+
delete statsMap[statName];
|
|
157
|
+
}
|
|
158
|
+
Object.assign(statsMap, reorderedStats);
|
|
159
|
+
ORDERED_STATS_CACHE.set(stats, { orderedStatNames, statCount });
|
|
160
|
+
}
|
|
91
161
|
|
|
92
162
|
// dist/utils/log.js
|
|
93
163
|
var import_log = require("@probe.gl/log");
|
|
@@ -102,19 +172,75 @@ function uid(id = "id") {
|
|
|
102
172
|
}
|
|
103
173
|
|
|
104
174
|
// dist/adapter/resources/resource.js
|
|
175
|
+
var CPU_HOTSPOT_PROFILER_MODULE = "cpu-hotspot-profiler";
|
|
176
|
+
var RESOURCE_COUNTS_STATS = "GPU Resource Counts";
|
|
177
|
+
var LEGACY_RESOURCE_COUNTS_STATS = "Resource Counts";
|
|
178
|
+
var GPU_TIME_AND_MEMORY_STATS2 = "GPU Time and Memory";
|
|
179
|
+
var BASE_RESOURCE_COUNT_ORDER = [
|
|
180
|
+
"Resources",
|
|
181
|
+
"Buffers",
|
|
182
|
+
"Textures",
|
|
183
|
+
"Samplers",
|
|
184
|
+
"TextureViews",
|
|
185
|
+
"Framebuffers",
|
|
186
|
+
"QuerySets",
|
|
187
|
+
"Shaders",
|
|
188
|
+
"RenderPipelines",
|
|
189
|
+
"ComputePipelines",
|
|
190
|
+
"PipelineLayouts",
|
|
191
|
+
"VertexArrays",
|
|
192
|
+
"RenderPasss",
|
|
193
|
+
"ComputePasss",
|
|
194
|
+
"CommandEncoders",
|
|
195
|
+
"CommandBuffers"
|
|
196
|
+
];
|
|
197
|
+
var WEBGL_RESOURCE_COUNT_ORDER = [
|
|
198
|
+
"Resources",
|
|
199
|
+
"Buffers",
|
|
200
|
+
"Textures",
|
|
201
|
+
"Samplers",
|
|
202
|
+
"TextureViews",
|
|
203
|
+
"Framebuffers",
|
|
204
|
+
"QuerySets",
|
|
205
|
+
"Shaders",
|
|
206
|
+
"RenderPipelines",
|
|
207
|
+
"SharedRenderPipelines",
|
|
208
|
+
"ComputePipelines",
|
|
209
|
+
"PipelineLayouts",
|
|
210
|
+
"VertexArrays",
|
|
211
|
+
"RenderPasss",
|
|
212
|
+
"ComputePasss",
|
|
213
|
+
"CommandEncoders",
|
|
214
|
+
"CommandBuffers"
|
|
215
|
+
];
|
|
216
|
+
var BASE_RESOURCE_COUNT_STAT_ORDER = BASE_RESOURCE_COUNT_ORDER.flatMap((resourceType) => [
|
|
217
|
+
`${resourceType} Created`,
|
|
218
|
+
`${resourceType} Active`
|
|
219
|
+
]);
|
|
220
|
+
var WEBGL_RESOURCE_COUNT_STAT_ORDER = WEBGL_RESOURCE_COUNT_ORDER.flatMap((resourceType) => [
|
|
221
|
+
`${resourceType} Created`,
|
|
222
|
+
`${resourceType} Active`
|
|
223
|
+
]);
|
|
224
|
+
var ORDERED_STATS_CACHE2 = /* @__PURE__ */ new WeakMap();
|
|
225
|
+
var ORDERED_STAT_NAME_SET_CACHE2 = /* @__PURE__ */ new WeakMap();
|
|
105
226
|
var Resource = class {
|
|
106
227
|
toString() {
|
|
107
228
|
return `${this[Symbol.toStringTag] || this.constructor.name}:"${this.id}"`;
|
|
108
229
|
}
|
|
109
230
|
/** props.id, for debugging. */
|
|
110
231
|
id;
|
|
232
|
+
/** The props that this resource was created with */
|
|
111
233
|
props;
|
|
234
|
+
/** User data object, reserved for the application */
|
|
112
235
|
userData = {};
|
|
236
|
+
/** The device that this resource is associated with - TODO can we remove this dup? */
|
|
113
237
|
_device;
|
|
114
238
|
/** Whether this resource has been destroyed */
|
|
115
239
|
destroyed = false;
|
|
116
240
|
/** For resources that allocate GPU memory */
|
|
117
241
|
allocatedBytes = 0;
|
|
242
|
+
/** Stats bucket currently holding the tracked allocation */
|
|
243
|
+
allocatedBytesName = null;
|
|
118
244
|
/** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
|
|
119
245
|
_attachedResources = /* @__PURE__ */ new Set();
|
|
120
246
|
/**
|
|
@@ -136,6 +262,9 @@ var Resource = class {
|
|
|
136
262
|
* destroy can be called on any resource to release it before it is garbage collected.
|
|
137
263
|
*/
|
|
138
264
|
destroy() {
|
|
265
|
+
if (this.destroyed) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
139
268
|
this.destroyResource();
|
|
140
269
|
}
|
|
141
270
|
/** @deprecated Use destroy() */
|
|
@@ -174,7 +303,7 @@ var Resource = class {
|
|
|
174
303
|
}
|
|
175
304
|
/** Destroy all owned resources. Make sure the resources are no longer needed before calling. */
|
|
176
305
|
destroyAttachedResources() {
|
|
177
|
-
for (const resource of
|
|
306
|
+
for (const resource of this._attachedResources) {
|
|
178
307
|
resource.destroy();
|
|
179
308
|
}
|
|
180
309
|
this._attachedResources = /* @__PURE__ */ new Set();
|
|
@@ -182,37 +311,107 @@ var Resource = class {
|
|
|
182
311
|
// PROTECTED METHODS
|
|
183
312
|
/** Perform all destroy steps. Can be called by derived resources when overriding destroy() */
|
|
184
313
|
destroyResource() {
|
|
314
|
+
if (this.destroyed) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
185
317
|
this.destroyAttachedResources();
|
|
186
318
|
this.removeStats();
|
|
187
319
|
this.destroyed = true;
|
|
188
320
|
}
|
|
189
321
|
/** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
|
|
190
322
|
removeStats() {
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
|
|
323
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
324
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
325
|
+
const statsObjects = [
|
|
326
|
+
this._device.statsManager.getStats(RESOURCE_COUNTS_STATS),
|
|
327
|
+
this._device.statsManager.getStats(LEGACY_RESOURCE_COUNTS_STATS)
|
|
328
|
+
];
|
|
329
|
+
const orderedStatNames = getResourceCountStatOrder(this._device);
|
|
330
|
+
for (const stats of statsObjects) {
|
|
331
|
+
initializeStats2(stats, orderedStatNames);
|
|
332
|
+
}
|
|
333
|
+
const name2 = this.getStatsName();
|
|
334
|
+
for (const stats of statsObjects) {
|
|
335
|
+
stats.get("Resources Active").decrementCount();
|
|
336
|
+
stats.get(`${name2}s Active`).decrementCount();
|
|
337
|
+
}
|
|
338
|
+
if (profiler) {
|
|
339
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
340
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
341
|
+
}
|
|
194
342
|
}
|
|
195
343
|
/** Called by subclass to track memory allocations */
|
|
196
|
-
trackAllocatedMemory(bytes, name2 = this
|
|
197
|
-
const
|
|
344
|
+
trackAllocatedMemory(bytes, name2 = this.getStatsName()) {
|
|
345
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
346
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
347
|
+
const stats = this._device.statsManager.getStats(GPU_TIME_AND_MEMORY_STATS2);
|
|
348
|
+
if (this.allocatedBytes > 0 && this.allocatedBytesName) {
|
|
349
|
+
stats.get("GPU Memory").subtractCount(this.allocatedBytes);
|
|
350
|
+
stats.get(`${this.allocatedBytesName} Memory`).subtractCount(this.allocatedBytes);
|
|
351
|
+
}
|
|
198
352
|
stats.get("GPU Memory").addCount(bytes);
|
|
199
353
|
stats.get(`${name2} Memory`).addCount(bytes);
|
|
354
|
+
if (profiler) {
|
|
355
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
356
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
357
|
+
}
|
|
200
358
|
this.allocatedBytes = bytes;
|
|
359
|
+
this.allocatedBytesName = name2;
|
|
360
|
+
}
|
|
361
|
+
/** Called by subclass to track handle-backed memory allocations separately from owned allocations */
|
|
362
|
+
trackReferencedMemory(bytes, name2 = this.getStatsName()) {
|
|
363
|
+
this.trackAllocatedMemory(bytes, `Referenced ${name2}`);
|
|
201
364
|
}
|
|
202
365
|
/** Called by subclass to track memory deallocations */
|
|
203
|
-
trackDeallocatedMemory(name2 = this
|
|
204
|
-
|
|
366
|
+
trackDeallocatedMemory(name2 = this.getStatsName()) {
|
|
367
|
+
if (this.allocatedBytes === 0) {
|
|
368
|
+
this.allocatedBytesName = null;
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
372
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
373
|
+
const stats = this._device.statsManager.getStats(GPU_TIME_AND_MEMORY_STATS2);
|
|
205
374
|
stats.get("GPU Memory").subtractCount(this.allocatedBytes);
|
|
206
|
-
stats.get(`${name2} Memory`).subtractCount(this.allocatedBytes);
|
|
375
|
+
stats.get(`${this.allocatedBytesName || name2} Memory`).subtractCount(this.allocatedBytes);
|
|
376
|
+
if (profiler) {
|
|
377
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
378
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
379
|
+
}
|
|
207
380
|
this.allocatedBytes = 0;
|
|
381
|
+
this.allocatedBytesName = null;
|
|
382
|
+
}
|
|
383
|
+
/** Called by subclass to deallocate handle-backed memory tracked via trackReferencedMemory() */
|
|
384
|
+
trackDeallocatedReferencedMemory(name2 = this.getStatsName()) {
|
|
385
|
+
this.trackDeallocatedMemory(`Referenced ${name2}`);
|
|
208
386
|
}
|
|
209
387
|
/** Called by resource constructor to track object creation */
|
|
210
388
|
addStats() {
|
|
211
|
-
const
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
389
|
+
const name2 = this.getStatsName();
|
|
390
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
391
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
392
|
+
const statsObjects = [
|
|
393
|
+
this._device.statsManager.getStats(RESOURCE_COUNTS_STATS),
|
|
394
|
+
this._device.statsManager.getStats(LEGACY_RESOURCE_COUNTS_STATS)
|
|
395
|
+
];
|
|
396
|
+
const orderedStatNames = getResourceCountStatOrder(this._device);
|
|
397
|
+
for (const stats of statsObjects) {
|
|
398
|
+
initializeStats2(stats, orderedStatNames);
|
|
399
|
+
}
|
|
400
|
+
for (const stats of statsObjects) {
|
|
401
|
+
stats.get("Resources Created").incrementCount();
|
|
402
|
+
stats.get("Resources Active").incrementCount();
|
|
403
|
+
stats.get(`${name2}s Created`).incrementCount();
|
|
404
|
+
stats.get(`${name2}s Active`).incrementCount();
|
|
405
|
+
}
|
|
406
|
+
if (profiler) {
|
|
407
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
408
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
409
|
+
}
|
|
410
|
+
recordTransientCanvasResourceCreate(this._device, name2);
|
|
411
|
+
}
|
|
412
|
+
/** Canonical resource name used for stats buckets. */
|
|
413
|
+
getStatsName() {
|
|
414
|
+
return getCanonicalResourceName(this);
|
|
216
415
|
}
|
|
217
416
|
};
|
|
218
417
|
/** Default properties for resource */
|
|
@@ -230,6 +429,97 @@ function selectivelyMerge(props, defaultProps) {
|
|
|
230
429
|
}
|
|
231
430
|
return mergedProps;
|
|
232
431
|
}
|
|
432
|
+
function initializeStats2(stats, orderedStatNames) {
|
|
433
|
+
const statsMap = stats.stats;
|
|
434
|
+
let addedOrderedStat = false;
|
|
435
|
+
for (const statName of orderedStatNames) {
|
|
436
|
+
if (!statsMap[statName]) {
|
|
437
|
+
stats.get(statName);
|
|
438
|
+
addedOrderedStat = true;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
const statCount = Object.keys(statsMap).length;
|
|
442
|
+
const cachedStats = ORDERED_STATS_CACHE2.get(stats);
|
|
443
|
+
if (!addedOrderedStat && (cachedStats == null ? void 0 : cachedStats.orderedStatNames) === orderedStatNames && cachedStats.statCount === statCount) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
const reorderedStats = {};
|
|
447
|
+
let orderedStatNamesSet = ORDERED_STAT_NAME_SET_CACHE2.get(orderedStatNames);
|
|
448
|
+
if (!orderedStatNamesSet) {
|
|
449
|
+
orderedStatNamesSet = new Set(orderedStatNames);
|
|
450
|
+
ORDERED_STAT_NAME_SET_CACHE2.set(orderedStatNames, orderedStatNamesSet);
|
|
451
|
+
}
|
|
452
|
+
for (const statName of orderedStatNames) {
|
|
453
|
+
if (statsMap[statName]) {
|
|
454
|
+
reorderedStats[statName] = statsMap[statName];
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
for (const [statName, stat] of Object.entries(statsMap)) {
|
|
458
|
+
if (!orderedStatNamesSet.has(statName)) {
|
|
459
|
+
reorderedStats[statName] = stat;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
for (const statName of Object.keys(statsMap)) {
|
|
463
|
+
delete statsMap[statName];
|
|
464
|
+
}
|
|
465
|
+
Object.assign(statsMap, reorderedStats);
|
|
466
|
+
ORDERED_STATS_CACHE2.set(stats, { orderedStatNames, statCount });
|
|
467
|
+
}
|
|
468
|
+
function getResourceCountStatOrder(device) {
|
|
469
|
+
return device.type === "webgl" ? WEBGL_RESOURCE_COUNT_STAT_ORDER : BASE_RESOURCE_COUNT_STAT_ORDER;
|
|
470
|
+
}
|
|
471
|
+
function getCpuHotspotProfiler(device) {
|
|
472
|
+
const profiler = device.userData[CPU_HOTSPOT_PROFILER_MODULE];
|
|
473
|
+
return (profiler == null ? void 0 : profiler.enabled) ? profiler : null;
|
|
474
|
+
}
|
|
475
|
+
function getTimestamp() {
|
|
476
|
+
var _a, _b;
|
|
477
|
+
return ((_b = (_a = globalThis.performance) == null ? void 0 : _a.now) == null ? void 0 : _b.call(_a)) ?? Date.now();
|
|
478
|
+
}
|
|
479
|
+
function recordTransientCanvasResourceCreate(device, name2) {
|
|
480
|
+
const profiler = getCpuHotspotProfiler(device);
|
|
481
|
+
if (!profiler || !profiler.activeDefaultFramebufferAcquireDepth) {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
profiler.transientCanvasResourceCreates = (profiler.transientCanvasResourceCreates || 0) + 1;
|
|
485
|
+
switch (name2) {
|
|
486
|
+
case "Texture":
|
|
487
|
+
profiler.transientCanvasTextureCreates = (profiler.transientCanvasTextureCreates || 0) + 1;
|
|
488
|
+
break;
|
|
489
|
+
case "TextureView":
|
|
490
|
+
profiler.transientCanvasTextureViewCreates = (profiler.transientCanvasTextureViewCreates || 0) + 1;
|
|
491
|
+
break;
|
|
492
|
+
case "Sampler":
|
|
493
|
+
profiler.transientCanvasSamplerCreates = (profiler.transientCanvasSamplerCreates || 0) + 1;
|
|
494
|
+
break;
|
|
495
|
+
case "Framebuffer":
|
|
496
|
+
profiler.transientCanvasFramebufferCreates = (profiler.transientCanvasFramebufferCreates || 0) + 1;
|
|
497
|
+
break;
|
|
498
|
+
default:
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
function getCanonicalResourceName(resource) {
|
|
503
|
+
let prototype = Object.getPrototypeOf(resource);
|
|
504
|
+
while (prototype) {
|
|
505
|
+
const parentPrototype = Object.getPrototypeOf(prototype);
|
|
506
|
+
if (!parentPrototype || parentPrototype === Resource.prototype) {
|
|
507
|
+
return getPrototypeToStringTag(prototype) || resource[Symbol.toStringTag] || resource.constructor.name;
|
|
508
|
+
}
|
|
509
|
+
prototype = parentPrototype;
|
|
510
|
+
}
|
|
511
|
+
return resource[Symbol.toStringTag] || resource.constructor.name;
|
|
512
|
+
}
|
|
513
|
+
function getPrototypeToStringTag(prototype) {
|
|
514
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, Symbol.toStringTag);
|
|
515
|
+
if (typeof (descriptor == null ? void 0 : descriptor.get) === "function") {
|
|
516
|
+
return descriptor.get.call(prototype);
|
|
517
|
+
}
|
|
518
|
+
if (typeof (descriptor == null ? void 0 : descriptor.value) === "string") {
|
|
519
|
+
return descriptor.value;
|
|
520
|
+
}
|
|
521
|
+
return null;
|
|
522
|
+
}
|
|
233
523
|
|
|
234
524
|
// dist/adapter/resources/buffer.js
|
|
235
525
|
var _Buffer = class extends Resource {
|
|
@@ -238,7 +528,7 @@ var _Buffer = class extends Resource {
|
|
|
238
528
|
}
|
|
239
529
|
/** The usage with which this buffer was created */
|
|
240
530
|
usage;
|
|
241
|
-
/** For index buffers, whether indices are 16 or 32 bit */
|
|
531
|
+
/** For index buffers, whether indices are 8, 16 or 32 bit. Note: uint8 indices are automatically converted to uint16 for WebGPU compatibility */
|
|
242
532
|
indexType;
|
|
243
533
|
/** "Time" of last update, can be used to check if redraw is needed */
|
|
244
534
|
updateTimestamp;
|
|
@@ -249,6 +539,8 @@ var _Buffer = class extends Resource {
|
|
|
249
539
|
deducedProps.indexType = "uint32";
|
|
250
540
|
} else if (props.data instanceof Uint16Array) {
|
|
251
541
|
deducedProps.indexType = "uint16";
|
|
542
|
+
} else if (props.data instanceof Uint8Array) {
|
|
543
|
+
deducedProps.indexType = "uint8";
|
|
252
544
|
}
|
|
253
545
|
}
|
|
254
546
|
delete deducedProps.data;
|
|
@@ -267,15 +559,23 @@ var _Buffer = class extends Resource {
|
|
|
267
559
|
/** A partial CPU-side copy of the data in this buffer, for debugging purposes */
|
|
268
560
|
debugData = new ArrayBuffer(0);
|
|
269
561
|
/** This doesn't handle partial non-zero offset updates correctly */
|
|
270
|
-
_setDebugData(data,
|
|
271
|
-
|
|
562
|
+
_setDebugData(data, _byteOffset, byteLength) {
|
|
563
|
+
let arrayBufferView = null;
|
|
564
|
+
let arrayBuffer2;
|
|
565
|
+
if (ArrayBuffer.isView(data)) {
|
|
566
|
+
arrayBufferView = data;
|
|
567
|
+
arrayBuffer2 = data.buffer;
|
|
568
|
+
} else {
|
|
569
|
+
arrayBuffer2 = data;
|
|
570
|
+
}
|
|
272
571
|
const debugDataLength = Math.min(data ? data.byteLength : byteLength, _Buffer.DEBUG_DATA_MAX_LENGTH);
|
|
273
572
|
if (arrayBuffer2 === null) {
|
|
274
573
|
this.debugData = new ArrayBuffer(debugDataLength);
|
|
275
|
-
} else if (byteOffset === 0 && byteLength === arrayBuffer2.byteLength) {
|
|
276
|
-
this.debugData = arrayBuffer2.slice(0, debugDataLength);
|
|
277
574
|
} else {
|
|
278
|
-
|
|
575
|
+
const sourceByteOffset = Math.min((arrayBufferView == null ? void 0 : arrayBufferView.byteOffset) || 0, arrayBuffer2.byteLength);
|
|
576
|
+
const availableByteLength = Math.max(0, arrayBuffer2.byteLength - sourceByteOffset);
|
|
577
|
+
const copyByteLength = Math.min(debugDataLength, availableByteLength);
|
|
578
|
+
this.debugData = new Uint8Array(arrayBuffer2, sourceByteOffset, copyByteLength).slice().buffer;
|
|
279
579
|
}
|
|
280
580
|
}
|
|
281
581
|
};
|
|
@@ -309,61 +609,73 @@ __publicField(Buffer2, "defaultProps", {
|
|
|
309
609
|
onMapped: void 0
|
|
310
610
|
});
|
|
311
611
|
|
|
312
|
-
// dist/shadertypes/data-types/
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
signedType,
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
case "sint8":
|
|
333
|
-
return "snorm8";
|
|
334
|
-
case "uint16":
|
|
335
|
-
return "unorm16";
|
|
336
|
-
case "sint16":
|
|
337
|
-
return "snorm16";
|
|
338
|
-
default:
|
|
339
|
-
return dataType;
|
|
612
|
+
// dist/shadertypes/data-types/data-type-decoder.js
|
|
613
|
+
var DataTypeDecoder = class {
|
|
614
|
+
/**
|
|
615
|
+
* Gets info about a data type constant (signed or normalized)
|
|
616
|
+
* @returns underlying primitive / signed types, byte length, normalization, integer, signed flags
|
|
617
|
+
*/
|
|
618
|
+
getDataTypeInfo(type) {
|
|
619
|
+
const [signedType, primitiveType, byteLength] = NORMALIZED_TYPE_MAP[type];
|
|
620
|
+
const normalized = type.includes("norm");
|
|
621
|
+
const integer = !normalized && !type.startsWith("float");
|
|
622
|
+
const signed = type.startsWith("s");
|
|
623
|
+
return {
|
|
624
|
+
signedType,
|
|
625
|
+
primitiveType,
|
|
626
|
+
byteLength,
|
|
627
|
+
normalized,
|
|
628
|
+
integer,
|
|
629
|
+
signed
|
|
630
|
+
// TODO - add webglOnly flag
|
|
631
|
+
};
|
|
340
632
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
633
|
+
/** Build a vertex format from a signed data type and a component */
|
|
634
|
+
getNormalizedDataType(signedDataType) {
|
|
635
|
+
const dataType = signedDataType;
|
|
636
|
+
switch (dataType) {
|
|
637
|
+
case "uint8":
|
|
638
|
+
return "unorm8";
|
|
639
|
+
case "sint8":
|
|
640
|
+
return "snorm8";
|
|
641
|
+
case "uint16":
|
|
642
|
+
return "unorm16";
|
|
643
|
+
case "sint16":
|
|
644
|
+
return "snorm16";
|
|
645
|
+
default:
|
|
646
|
+
return dataType;
|
|
647
|
+
}
|
|
350
648
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
649
|
+
/** Align offset to 1, 2 or 4 elements (4, 8 or 16 bytes) */
|
|
650
|
+
alignTo(size, count) {
|
|
651
|
+
switch (count) {
|
|
652
|
+
case 1:
|
|
653
|
+
return size;
|
|
654
|
+
case 2:
|
|
655
|
+
return size + size % 2;
|
|
656
|
+
default:
|
|
657
|
+
return size + (4 - size % 4) % 4;
|
|
658
|
+
}
|
|
356
659
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
660
|
+
/** Returns the VariableShaderType that corresponds to a typed array */
|
|
661
|
+
getDataType(arrayOrType) {
|
|
662
|
+
const Constructor = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType;
|
|
663
|
+
if (Constructor === Uint8ClampedArray) {
|
|
664
|
+
return "uint8";
|
|
665
|
+
}
|
|
666
|
+
const info = Object.values(NORMALIZED_TYPE_MAP).find((entry) => Constructor === entry[4]);
|
|
667
|
+
if (!info) {
|
|
668
|
+
throw new Error(Constructor.name);
|
|
669
|
+
}
|
|
670
|
+
return info[0];
|
|
360
671
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
672
|
+
/** Returns the TypedArray that corresponds to a shader data type */
|
|
673
|
+
getTypedArrayConstructor(type) {
|
|
674
|
+
const [, , , , Constructor] = NORMALIZED_TYPE_MAP[type];
|
|
675
|
+
return Constructor;
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
var dataTypeDecoder = new DataTypeDecoder();
|
|
367
679
|
var NORMALIZED_TYPE_MAP = {
|
|
368
680
|
uint8: ["uint8", "u32", 1, false, Uint8Array],
|
|
369
681
|
sint8: ["sint8", "i32", 1, false, Int8Array],
|
|
@@ -379,87 +691,99 @@ var NORMALIZED_TYPE_MAP = {
|
|
|
379
691
|
sint32: ["sint32", "i32", 4, false, Int32Array]
|
|
380
692
|
};
|
|
381
693
|
|
|
382
|
-
// dist/shadertypes/vertex-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
type
|
|
395
|
-
components
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
694
|
+
// dist/shadertypes/vertex-types/vertex-format-decoder.js
|
|
695
|
+
var VertexFormatDecoder = class {
|
|
696
|
+
/**
|
|
697
|
+
* Decodes a vertex format, returning type, components, byte length and flags (integer, signed, normalized)
|
|
698
|
+
*/
|
|
699
|
+
getVertexFormatInfo(format) {
|
|
700
|
+
let webglOnly;
|
|
701
|
+
if (format.endsWith("-webgl")) {
|
|
702
|
+
format.replace("-webgl", "");
|
|
703
|
+
webglOnly = true;
|
|
704
|
+
}
|
|
705
|
+
const [type_, count] = format.split("x");
|
|
706
|
+
const type = type_;
|
|
707
|
+
const components = count ? parseInt(count) : 1;
|
|
708
|
+
const decodedType = dataTypeDecoder.getDataTypeInfo(type);
|
|
709
|
+
const result = {
|
|
710
|
+
type,
|
|
711
|
+
components,
|
|
712
|
+
byteLength: decodedType.byteLength * components,
|
|
713
|
+
integer: decodedType.integer,
|
|
714
|
+
signed: decodedType.signed,
|
|
715
|
+
normalized: decodedType.normalized
|
|
716
|
+
};
|
|
717
|
+
if (webglOnly) {
|
|
718
|
+
result.webglOnly = true;
|
|
719
|
+
}
|
|
720
|
+
return result;
|
|
721
|
+
}
|
|
722
|
+
/** Build a vertex format from a signed data type and a component */
|
|
723
|
+
makeVertexFormat(signedDataType, components, normalized) {
|
|
724
|
+
const dataType = normalized ? dataTypeDecoder.getNormalizedDataType(signedDataType) : signedDataType;
|
|
725
|
+
switch (dataType) {
|
|
726
|
+
case "unorm8":
|
|
727
|
+
if (components === 1) {
|
|
728
|
+
return "unorm8";
|
|
729
|
+
}
|
|
730
|
+
if (components === 3) {
|
|
731
|
+
return "unorm8x3-webgl";
|
|
732
|
+
}
|
|
733
|
+
return `${dataType}x${components}`;
|
|
734
|
+
case "snorm8":
|
|
735
|
+
case "uint8":
|
|
736
|
+
case "sint8":
|
|
737
|
+
case "uint16":
|
|
738
|
+
case "sint16":
|
|
739
|
+
case "unorm16":
|
|
740
|
+
case "snorm16":
|
|
741
|
+
case "float16":
|
|
742
|
+
if (components === 1 || components === 3) {
|
|
743
|
+
throw new Error(`size: ${components}`);
|
|
744
|
+
}
|
|
745
|
+
return `${dataType}x${components}`;
|
|
746
|
+
default:
|
|
747
|
+
return components === 1 ? dataType : `${dataType}x${components}`;
|
|
748
|
+
}
|
|
436
749
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
vertexType = "float32";
|
|
446
|
-
break;
|
|
447
|
-
case "i32":
|
|
448
|
-
vertexType = "sint32";
|
|
449
|
-
break;
|
|
450
|
-
case "u32":
|
|
451
|
-
vertexType = "uint32";
|
|
452
|
-
break;
|
|
453
|
-
case "f16":
|
|
454
|
-
return opts.components <= 2 ? "float16x2" : "float16x4";
|
|
750
|
+
/** Get the vertex format for an attribute with TypedArray and size */
|
|
751
|
+
getVertexFormatFromAttribute(typedArray, size, normalized) {
|
|
752
|
+
if (!size || size > 4) {
|
|
753
|
+
throw new Error(`size ${size}`);
|
|
754
|
+
}
|
|
755
|
+
const components = size;
|
|
756
|
+
const signedDataType = dataTypeDecoder.getDataType(typedArray);
|
|
757
|
+
return this.makeVertexFormat(signedDataType, components, normalized);
|
|
455
758
|
}
|
|
456
|
-
|
|
457
|
-
|
|
759
|
+
/**
|
|
760
|
+
* Return a "default" vertex format for a certain shader data type
|
|
761
|
+
* The simplest vertex format that matches the shader attribute's data type
|
|
762
|
+
*/
|
|
763
|
+
getCompatibleVertexFormat(opts) {
|
|
764
|
+
let vertexType;
|
|
765
|
+
switch (opts.primitiveType) {
|
|
766
|
+
case "f32":
|
|
767
|
+
vertexType = "float32";
|
|
768
|
+
break;
|
|
769
|
+
case "i32":
|
|
770
|
+
vertexType = "sint32";
|
|
771
|
+
break;
|
|
772
|
+
case "u32":
|
|
773
|
+
vertexType = "uint32";
|
|
774
|
+
break;
|
|
775
|
+
case "f16":
|
|
776
|
+
return opts.components <= 2 ? "float16x2" : "float16x4";
|
|
777
|
+
}
|
|
778
|
+
if (opts.components === 1) {
|
|
779
|
+
return vertexType;
|
|
780
|
+
}
|
|
781
|
+
return `${vertexType}x${opts.components}`;
|
|
458
782
|
}
|
|
459
|
-
|
|
460
|
-
|
|
783
|
+
};
|
|
784
|
+
var vertexFormatDecoder = new VertexFormatDecoder();
|
|
461
785
|
|
|
462
|
-
// dist/shadertypes/
|
|
786
|
+
// dist/shadertypes/texture-types/texture-format-table.js
|
|
463
787
|
var texture_compression_bc = "texture-compression-bc";
|
|
464
788
|
var texture_compression_astc = "texture-compression-astc";
|
|
465
789
|
var texture_compression_etc2 = "texture-compression-etc2";
|
|
@@ -470,6 +794,7 @@ var float32_renderable = "float32-renderable-webgl";
|
|
|
470
794
|
var float16_renderable = "float16-renderable-webgl";
|
|
471
795
|
var rgb9e5ufloat_renderable = "rgb9e5ufloat-renderable-webgl";
|
|
472
796
|
var snorm8_renderable = "snorm8-renderable-webgl";
|
|
797
|
+
var norm16_webgl = "norm16-webgl";
|
|
473
798
|
var norm16_renderable = "norm16-renderable-webgl";
|
|
474
799
|
var snorm16_renderable = "snorm16-renderable-webgl";
|
|
475
800
|
var float32_filterable = "float32-filterable";
|
|
@@ -503,16 +828,16 @@ var TEXTURE_FORMAT_COLOR_DEPTH_TABLE = {
|
|
|
503
828
|
"rgba8sint": {},
|
|
504
829
|
"bgra8unorm": {},
|
|
505
830
|
"bgra8unorm-srgb": {},
|
|
506
|
-
"r16unorm": { f: norm16_renderable },
|
|
507
|
-
"rg16unorm": { render: norm16_renderable },
|
|
508
|
-
"rgb16unorm-webgl": { f:
|
|
831
|
+
"r16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
832
|
+
"rg16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
833
|
+
"rgb16unorm-webgl": { f: norm16_webgl, render: false },
|
|
509
834
|
// rgb not renderable
|
|
510
|
-
"rgba16unorm": { render: norm16_renderable },
|
|
511
|
-
"r16snorm": { f: snorm16_renderable },
|
|
512
|
-
"rg16snorm": { render: snorm16_renderable },
|
|
513
|
-
"rgb16snorm-webgl": { f:
|
|
835
|
+
"rgba16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
836
|
+
"r16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
837
|
+
"rg16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
838
|
+
"rgb16snorm-webgl": { f: norm16_webgl, render: false },
|
|
514
839
|
// rgb not renderable
|
|
515
|
-
"rgba16snorm": { render: snorm16_renderable },
|
|
840
|
+
"rgba16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
516
841
|
"r16uint": {},
|
|
517
842
|
"rg16uint": {},
|
|
518
843
|
"rgba16uint": {},
|
|
@@ -615,7 +940,7 @@ var TEXTURE_FORMAT_COMPRESSED_TABLE = {
|
|
|
615
940
|
// WEBGL_compressed_texture_pvrtc
|
|
616
941
|
"pvrtc-rgb4unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
617
942
|
"pvrtc-rgba4unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
618
|
-
"pvrtc-
|
|
943
|
+
"pvrtc-rgb2unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
619
944
|
"pvrtc-rgba2unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
620
945
|
// WEBGL_compressed_texture_etc1
|
|
621
946
|
"etc1-rbg-unorm-webgl": { f: texture_compression_etc1_webgl },
|
|
@@ -629,7 +954,10 @@ var TEXTURE_FORMAT_TABLE = {
|
|
|
629
954
|
...TEXTURE_FORMAT_COMPRESSED_TABLE
|
|
630
955
|
};
|
|
631
956
|
|
|
632
|
-
// dist/shadertypes/
|
|
957
|
+
// dist/shadertypes/texture-types/texture-format-decoder.js
|
|
958
|
+
var RGB_FORMAT_REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
|
|
959
|
+
var COLOR_FORMAT_PREFIXES = ["rgb", "rgba", "bgra"];
|
|
960
|
+
var DEPTH_FORMAT_PREFIXES = ["depth", "stencil"];
|
|
633
961
|
var COMPRESSED_TEXTURE_FORMAT_PREFIXES = [
|
|
634
962
|
"bc1",
|
|
635
963
|
"bc2",
|
|
@@ -645,49 +973,71 @@ var COMPRESSED_TEXTURE_FORMAT_PREFIXES = [
|
|
|
645
973
|
"astc",
|
|
646
974
|
"pvrtc"
|
|
647
975
|
];
|
|
648
|
-
var RGB_FORMAT_REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
|
|
649
976
|
var TextureFormatDecoder = class {
|
|
650
|
-
/** Returns information about a texture format, e.g. attatchment type, components, byte length and flags (integer, signed, normalized) */
|
|
651
|
-
getInfo(format) {
|
|
652
|
-
return getTextureFormatInfo(format);
|
|
653
|
-
}
|
|
654
977
|
/** Checks if a texture format is color */
|
|
655
978
|
isColor(format) {
|
|
656
|
-
return
|
|
979
|
+
return COLOR_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
657
980
|
}
|
|
658
981
|
/** Checks if a texture format is depth or stencil */
|
|
659
982
|
isDepthStencil(format) {
|
|
660
|
-
return
|
|
983
|
+
return DEPTH_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
661
984
|
}
|
|
662
985
|
/** Checks if a texture format is compressed */
|
|
663
986
|
isCompressed(format) {
|
|
664
987
|
return COMPRESSED_TEXTURE_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
665
988
|
}
|
|
666
|
-
/**
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
989
|
+
/** Returns information about a texture format, e.g. attachment type, components, byte length and flags (integer, signed, normalized) */
|
|
990
|
+
getInfo(format) {
|
|
991
|
+
return getTextureFormatInfo(format);
|
|
992
|
+
}
|
|
993
|
+
/** "static" capabilities of a texture format. @note Needs to be adjusted against current device */
|
|
670
994
|
getCapabilities(format) {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
filter: info.filter ?? true,
|
|
677
|
-
blend: info.blend ?? true,
|
|
678
|
-
store: info.store ?? true
|
|
679
|
-
};
|
|
680
|
-
const formatInfo = getTextureFormatInfo(format);
|
|
681
|
-
const isDepthStencil = format.startsWith("depth") || format.startsWith("stencil");
|
|
682
|
-
const isSigned = formatInfo == null ? void 0 : formatInfo.signed;
|
|
683
|
-
const isInteger = formatInfo == null ? void 0 : formatInfo.integer;
|
|
684
|
-
const isWebGLSpecific = formatInfo == null ? void 0 : formatInfo.webgl;
|
|
685
|
-
formatCapabilities.render &&= !isSigned;
|
|
686
|
-
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
|
|
687
|
-
return formatCapabilities;
|
|
995
|
+
return getTextureFormatCapabilities(format);
|
|
996
|
+
}
|
|
997
|
+
/** Computes the memory layout for a texture, in particular including row byte alignment */
|
|
998
|
+
computeMemoryLayout(opts) {
|
|
999
|
+
return computeTextureMemoryLayout(opts);
|
|
688
1000
|
}
|
|
689
1001
|
};
|
|
690
1002
|
var textureFormatDecoder = new TextureFormatDecoder();
|
|
1003
|
+
function computeTextureMemoryLayout({ format, width, height, depth, byteAlignment }) {
|
|
1004
|
+
const formatInfo = textureFormatDecoder.getInfo(format);
|
|
1005
|
+
const { bytesPerPixel, bytesPerBlock = bytesPerPixel, blockWidth = 1, blockHeight = 1, compressed = false } = formatInfo;
|
|
1006
|
+
const blockColumns = compressed ? Math.ceil(width / blockWidth) : width;
|
|
1007
|
+
const blockRows = compressed ? Math.ceil(height / blockHeight) : height;
|
|
1008
|
+
const unpaddedBytesPerRow = blockColumns * bytesPerBlock;
|
|
1009
|
+
const bytesPerRow = Math.ceil(unpaddedBytesPerRow / byteAlignment) * byteAlignment;
|
|
1010
|
+
const rowsPerImage = blockRows;
|
|
1011
|
+
const byteLength = bytesPerRow * rowsPerImage * depth;
|
|
1012
|
+
return {
|
|
1013
|
+
bytesPerPixel,
|
|
1014
|
+
bytesPerRow,
|
|
1015
|
+
rowsPerImage,
|
|
1016
|
+
depthOrArrayLayers: depth,
|
|
1017
|
+
bytesPerImage: bytesPerRow * rowsPerImage,
|
|
1018
|
+
byteLength
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
function getTextureFormatCapabilities(format) {
|
|
1022
|
+
const info = getTextureFormatDefinition(format);
|
|
1023
|
+
const formatCapabilities = {
|
|
1024
|
+
format,
|
|
1025
|
+
create: info.f ?? true,
|
|
1026
|
+
render: info.render ?? true,
|
|
1027
|
+
filter: info.filter ?? true,
|
|
1028
|
+
blend: info.blend ?? true,
|
|
1029
|
+
store: info.store ?? true
|
|
1030
|
+
};
|
|
1031
|
+
const formatInfo = getTextureFormatInfo(format);
|
|
1032
|
+
const isDepthStencil = format.startsWith("depth") || format.startsWith("stencil");
|
|
1033
|
+
const isSigned = formatInfo == null ? void 0 : formatInfo.signed;
|
|
1034
|
+
const isInteger = formatInfo == null ? void 0 : formatInfo.integer;
|
|
1035
|
+
const isWebGLSpecific = formatInfo == null ? void 0 : formatInfo.webgl;
|
|
1036
|
+
const isCompressed = Boolean(formatInfo == null ? void 0 : formatInfo.compressed);
|
|
1037
|
+
formatCapabilities.render &&= !isDepthStencil && !isCompressed;
|
|
1038
|
+
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
|
|
1039
|
+
return formatCapabilities;
|
|
1040
|
+
}
|
|
691
1041
|
function getTextureFormatInfo(format) {
|
|
692
1042
|
let formatInfo = getTextureFormatInfoUsingTable(format);
|
|
693
1043
|
if (textureFormatDecoder.isCompressed(format)) {
|
|
@@ -696,19 +1046,20 @@ function getTextureFormatInfo(format) {
|
|
|
696
1046
|
formatInfo.bytesPerPixel = 1;
|
|
697
1047
|
formatInfo.srgb = false;
|
|
698
1048
|
formatInfo.compressed = true;
|
|
1049
|
+
formatInfo.bytesPerBlock = getCompressedTextureBlockByteLength(format);
|
|
699
1050
|
const blockSize = getCompressedTextureBlockSize(format);
|
|
700
1051
|
if (blockSize) {
|
|
701
1052
|
formatInfo.blockWidth = blockSize.blockWidth;
|
|
702
1053
|
formatInfo.blockHeight = blockSize.blockHeight;
|
|
703
1054
|
}
|
|
704
1055
|
}
|
|
705
|
-
const matches = RGB_FORMAT_REGEX.exec(format);
|
|
1056
|
+
const matches = !formatInfo.packed ? RGB_FORMAT_REGEX.exec(format) : null;
|
|
706
1057
|
if (matches) {
|
|
707
1058
|
const [, channels, length, type, srgb, suffix] = matches;
|
|
708
1059
|
const dataType = `${type}${length}`;
|
|
709
|
-
const decodedType = getDataTypeInfo(dataType);
|
|
1060
|
+
const decodedType = dataTypeDecoder.getDataTypeInfo(dataType);
|
|
710
1061
|
const bits = decodedType.byteLength * 8;
|
|
711
|
-
const components = channels.length;
|
|
1062
|
+
const components = (channels == null ? void 0 : channels.length) ?? 1;
|
|
712
1063
|
const bitsPerChannel = [
|
|
713
1064
|
bits,
|
|
714
1065
|
components >= 2 ? bits : 0,
|
|
@@ -725,7 +1076,7 @@ function getTextureFormatInfo(format) {
|
|
|
725
1076
|
signed: decodedType.signed,
|
|
726
1077
|
normalized: decodedType.normalized,
|
|
727
1078
|
bitsPerChannel,
|
|
728
|
-
bytesPerPixel: decodedType.byteLength *
|
|
1079
|
+
bytesPerPixel: decodedType.byteLength * components,
|
|
729
1080
|
packed: formatInfo.packed,
|
|
730
1081
|
srgb: formatInfo.srgb
|
|
731
1082
|
};
|
|
@@ -782,10 +1133,31 @@ function getCompressedTextureBlockSize(format) {
|
|
|
782
1133
|
const [, blockWidth, blockHeight] = matches;
|
|
783
1134
|
return { blockWidth: Number(blockWidth), blockHeight: Number(blockHeight) };
|
|
784
1135
|
}
|
|
1136
|
+
if (format.startsWith("bc") || format.startsWith("etc1") || format.startsWith("etc2") || format.startsWith("eac") || format.startsWith("atc")) {
|
|
1137
|
+
return { blockWidth: 4, blockHeight: 4 };
|
|
1138
|
+
}
|
|
1139
|
+
if (format.startsWith("pvrtc-rgb4") || format.startsWith("pvrtc-rgba4")) {
|
|
1140
|
+
return { blockWidth: 4, blockHeight: 4 };
|
|
1141
|
+
}
|
|
1142
|
+
if (format.startsWith("pvrtc-rgb2") || format.startsWith("pvrtc-rgba2")) {
|
|
1143
|
+
return { blockWidth: 8, blockHeight: 4 };
|
|
1144
|
+
}
|
|
785
1145
|
return null;
|
|
786
1146
|
}
|
|
1147
|
+
function getCompressedTextureBlockByteLength(format) {
|
|
1148
|
+
if (format.startsWith("bc1") || format.startsWith("bc4") || format.startsWith("etc1") || format.startsWith("etc2-rgb8") || format.startsWith("etc2-rgb8a1") || format.startsWith("eac-r11") || format === "atc-rgb-unorm-webgl") {
|
|
1149
|
+
return 8;
|
|
1150
|
+
}
|
|
1151
|
+
if (format.startsWith("bc2") || format.startsWith("bc3") || format.startsWith("bc5") || format.startsWith("bc6h") || format.startsWith("bc7") || format.startsWith("etc2-rgba8") || format.startsWith("eac-rg11") || format.startsWith("astc") || format === "atc-rgba-unorm-webgl" || format === "atc-rgbai-unorm-webgl") {
|
|
1152
|
+
return 16;
|
|
1153
|
+
}
|
|
1154
|
+
if (format.startsWith("pvrtc")) {
|
|
1155
|
+
return 8;
|
|
1156
|
+
}
|
|
1157
|
+
return 16;
|
|
1158
|
+
}
|
|
787
1159
|
|
|
788
|
-
// dist/image-
|
|
1160
|
+
// dist/shadertypes/image-types/image-types.js
|
|
789
1161
|
function isExternalImage(data) {
|
|
790
1162
|
return typeof ImageData !== "undefined" && data instanceof ImageData || typeof ImageBitmap !== "undefined" && data instanceof ImageBitmap || typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement || typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement || typeof VideoFrame !== "undefined" && data instanceof VideoFrame || typeof HTMLCanvasElement !== "undefined" && data instanceof HTMLCanvasElement || typeof OffscreenCanvas !== "undefined" && data instanceof OffscreenCanvas;
|
|
791
1163
|
}
|
|
@@ -808,6 +1180,53 @@ function getExternalImageSize(data) {
|
|
|
808
1180
|
// dist/adapter/device.js
|
|
809
1181
|
var DeviceLimits = class {
|
|
810
1182
|
};
|
|
1183
|
+
function formatErrorLogArguments(context, args) {
|
|
1184
|
+
const formattedContext = formatErrorLogValue(context);
|
|
1185
|
+
const formattedArgs = args.map(formatErrorLogValue).filter((arg) => arg !== void 0);
|
|
1186
|
+
return [formattedContext, ...formattedArgs].filter((arg) => arg !== void 0);
|
|
1187
|
+
}
|
|
1188
|
+
function formatErrorLogValue(value) {
|
|
1189
|
+
var _a;
|
|
1190
|
+
if (value === void 0) {
|
|
1191
|
+
return void 0;
|
|
1192
|
+
}
|
|
1193
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1194
|
+
return value;
|
|
1195
|
+
}
|
|
1196
|
+
if (value instanceof Error) {
|
|
1197
|
+
return value.message;
|
|
1198
|
+
}
|
|
1199
|
+
if (Array.isArray(value)) {
|
|
1200
|
+
return value.map(formatErrorLogValue);
|
|
1201
|
+
}
|
|
1202
|
+
if (typeof value === "object") {
|
|
1203
|
+
if (hasCustomToString(value)) {
|
|
1204
|
+
const stringValue = String(value);
|
|
1205
|
+
if (stringValue !== "[object Object]") {
|
|
1206
|
+
return stringValue;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
if (looksLikeGPUCompilationMessage(value)) {
|
|
1210
|
+
return formatGPUCompilationMessage(value);
|
|
1211
|
+
}
|
|
1212
|
+
return ((_a = value.constructor) == null ? void 0 : _a.name) || "Object";
|
|
1213
|
+
}
|
|
1214
|
+
return String(value);
|
|
1215
|
+
}
|
|
1216
|
+
function hasCustomToString(value) {
|
|
1217
|
+
return "toString" in value && typeof value.toString === "function" && value.toString !== Object.prototype.toString;
|
|
1218
|
+
}
|
|
1219
|
+
function looksLikeGPUCompilationMessage(value) {
|
|
1220
|
+
return "message" in value && "type" in value;
|
|
1221
|
+
}
|
|
1222
|
+
function formatGPUCompilationMessage(value) {
|
|
1223
|
+
const type = typeof value.type === "string" ? value.type : "message";
|
|
1224
|
+
const message = typeof value.message === "string" ? value.message : "";
|
|
1225
|
+
const lineNum = typeof value.lineNum === "number" ? value.lineNum : null;
|
|
1226
|
+
const linePos = typeof value.linePos === "number" ? value.linePos : null;
|
|
1227
|
+
const location = lineNum !== null && linePos !== null ? ` @ ${lineNum}:${linePos}` : lineNum !== null ? ` @ ${lineNum}` : "";
|
|
1228
|
+
return `${type}${location}: ${message}`.trim();
|
|
1229
|
+
}
|
|
811
1230
|
var DeviceFeatures = class {
|
|
812
1231
|
features;
|
|
813
1232
|
disabledFeatures;
|
|
@@ -838,19 +1257,24 @@ var _Device = class {
|
|
|
838
1257
|
userData = {};
|
|
839
1258
|
/** stats */
|
|
840
1259
|
statsManager = lumaStats;
|
|
1260
|
+
/** Internal per-device factory storage */
|
|
1261
|
+
_factories = {};
|
|
841
1262
|
/** An abstract timestamp used for change tracking */
|
|
842
1263
|
timestamp = 0;
|
|
843
1264
|
/** True if this device has been reused during device creation (app has multiple references) */
|
|
844
1265
|
_reused = false;
|
|
845
1266
|
/** Used by other luma.gl modules to store data on the device */
|
|
846
|
-
|
|
1267
|
+
_moduleData = {};
|
|
847
1268
|
_textureCaps = {};
|
|
1269
|
+
/** Internal timestamp query set used when GPU timing collection is enabled for this device. */
|
|
1270
|
+
_debugGPUTimeQuery = null;
|
|
848
1271
|
constructor(props) {
|
|
849
1272
|
this.props = { ..._Device.defaultProps, ...props };
|
|
850
1273
|
this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
|
|
851
1274
|
}
|
|
1275
|
+
// TODO - just expose the shadertypes decoders?
|
|
852
1276
|
getVertexFormatInfo(format) {
|
|
853
|
-
return getVertexFormatInfo(format);
|
|
1277
|
+
return vertexFormatDecoder.getVertexFormatInfo(format);
|
|
854
1278
|
}
|
|
855
1279
|
isVertexFormatSupported(format) {
|
|
856
1280
|
return true;
|
|
@@ -898,6 +1322,16 @@ var _Device = class {
|
|
|
898
1322
|
isTextureFormatCompressed(format) {
|
|
899
1323
|
return textureFormatDecoder.isCompressed(format);
|
|
900
1324
|
}
|
|
1325
|
+
/** Returns the compressed texture formats that can be created and sampled on this device */
|
|
1326
|
+
getSupportedCompressedTextureFormats() {
|
|
1327
|
+
const supportedFormats = [];
|
|
1328
|
+
for (const format of Object.keys(getTextureFormatTable())) {
|
|
1329
|
+
if (this.isTextureFormatCompressed(format) && this.isTextureFormatSupported(format)) {
|
|
1330
|
+
supportedFormats.push(format);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
return supportedFormats;
|
|
1334
|
+
}
|
|
901
1335
|
// DEBUG METHODS
|
|
902
1336
|
pushDebugGroup(groupLabel) {
|
|
903
1337
|
this.commandEncoder.pushDebugGroup(groupLabel);
|
|
@@ -942,7 +1376,8 @@ var _Device = class {
|
|
|
942
1376
|
reportError(error, context, ...args) {
|
|
943
1377
|
const isHandled = this.props.onError(error, context);
|
|
944
1378
|
if (!isHandled) {
|
|
945
|
-
|
|
1379
|
+
const logArguments = formatErrorLogArguments(context, args);
|
|
1380
|
+
return log.error(this.type === "webgl" ? "%cWebGL" : "%cWebGPU", "color: white; background: red; padding: 2px 6px; border-radius: 3px;", error.message, ...logArguments);
|
|
946
1381
|
}
|
|
947
1382
|
return () => {
|
|
948
1383
|
};
|
|
@@ -964,6 +1399,10 @@ or create a device with the 'debug: true' prop.`;
|
|
|
964
1399
|
}
|
|
965
1400
|
return this.canvasContext;
|
|
966
1401
|
}
|
|
1402
|
+
/** Create a fence sync object */
|
|
1403
|
+
createFence() {
|
|
1404
|
+
throw new Error("createFence() not implemented");
|
|
1405
|
+
}
|
|
967
1406
|
/** Create a RenderPass using the default CommandEncoder */
|
|
968
1407
|
beginRenderPass(props) {
|
|
969
1408
|
return this.commandEncoder.beginRenderPass(props);
|
|
@@ -972,6 +1411,78 @@ or create a device with the 'debug: true' prop.`;
|
|
|
972
1411
|
beginComputePass(props) {
|
|
973
1412
|
return this.commandEncoder.beginComputePass(props);
|
|
974
1413
|
}
|
|
1414
|
+
/**
|
|
1415
|
+
* Generate mipmaps for a WebGPU texture.
|
|
1416
|
+
* WebGPU textures must be created up front with the required mip count, usage flags, and a format that supports the chosen generation path.
|
|
1417
|
+
* WebGL uses `Texture.generateMipmapsWebGL()` directly because the backend manages mip generation on the texture object itself.
|
|
1418
|
+
*/
|
|
1419
|
+
generateMipmapsWebGPU(_texture) {
|
|
1420
|
+
throw new Error("not implemented");
|
|
1421
|
+
}
|
|
1422
|
+
/** Internal helper for creating a shareable WebGL render-pipeline implementation. */
|
|
1423
|
+
_createSharedRenderPipelineWebGL(_props) {
|
|
1424
|
+
throw new Error("_createSharedRenderPipelineWebGL() not implemented");
|
|
1425
|
+
}
|
|
1426
|
+
/** Internal WebGPU-only helper for retrieving the native bind-group layout for a pipeline group. */
|
|
1427
|
+
_createBindGroupLayoutWebGPU(_pipeline, _group) {
|
|
1428
|
+
throw new Error("_createBindGroupLayoutWebGPU() not implemented");
|
|
1429
|
+
}
|
|
1430
|
+
/** Internal WebGPU-only helper for creating a native bind group. */
|
|
1431
|
+
_createBindGroupWebGPU(_bindGroupLayout, _shaderLayout, _bindings, _group) {
|
|
1432
|
+
throw new Error("_createBindGroupWebGPU() not implemented");
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Internal helper that returns `true` when timestamp-query GPU timing should be
|
|
1436
|
+
* collected for this device.
|
|
1437
|
+
*/
|
|
1438
|
+
_supportsDebugGPUTime() {
|
|
1439
|
+
return this.features.has("timestamp-query") && Boolean(this.props.debug || this.props.debugGPUTime);
|
|
1440
|
+
}
|
|
1441
|
+
/**
|
|
1442
|
+
* Internal helper that enables device-managed GPU timing collection on the
|
|
1443
|
+
* default command encoder. Reuses the existing query set if timing is already enabled.
|
|
1444
|
+
*
|
|
1445
|
+
* @param queryCount - Number of timestamp slots reserved for profiled passes.
|
|
1446
|
+
* @returns The device-managed timestamp QuerySet, or `null` when timing is not supported or could not be enabled.
|
|
1447
|
+
*/
|
|
1448
|
+
_enableDebugGPUTime(queryCount = 256) {
|
|
1449
|
+
if (!this._supportsDebugGPUTime()) {
|
|
1450
|
+
return null;
|
|
1451
|
+
}
|
|
1452
|
+
if (this._debugGPUTimeQuery) {
|
|
1453
|
+
return this._debugGPUTimeQuery;
|
|
1454
|
+
}
|
|
1455
|
+
try {
|
|
1456
|
+
this._debugGPUTimeQuery = this.createQuerySet({ type: "timestamp", count: queryCount });
|
|
1457
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
1458
|
+
id: this.commandEncoder.props.id,
|
|
1459
|
+
timeProfilingQuerySet: this._debugGPUTimeQuery
|
|
1460
|
+
});
|
|
1461
|
+
} catch {
|
|
1462
|
+
this._debugGPUTimeQuery = null;
|
|
1463
|
+
}
|
|
1464
|
+
return this._debugGPUTimeQuery;
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Internal helper that disables device-managed GPU timing collection and restores
|
|
1468
|
+
* the default command encoder to an unprofiled state.
|
|
1469
|
+
*/
|
|
1470
|
+
_disableDebugGPUTime() {
|
|
1471
|
+
if (!this._debugGPUTimeQuery) {
|
|
1472
|
+
return;
|
|
1473
|
+
}
|
|
1474
|
+
if (this.commandEncoder.getTimeProfilingQuerySet() === this._debugGPUTimeQuery) {
|
|
1475
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
1476
|
+
id: this.commandEncoder.props.id
|
|
1477
|
+
});
|
|
1478
|
+
}
|
|
1479
|
+
this._debugGPUTimeQuery.destroy();
|
|
1480
|
+
this._debugGPUTimeQuery = null;
|
|
1481
|
+
}
|
|
1482
|
+
/** Internal helper that returns `true` when device-managed GPU timing is currently active. */
|
|
1483
|
+
_isDebugGPUTimeEnabled() {
|
|
1484
|
+
return this._debugGPUTimeQuery !== null;
|
|
1485
|
+
}
|
|
975
1486
|
// DEPRECATED METHODS
|
|
976
1487
|
/** @deprecated Use getDefaultCanvasContext() */
|
|
977
1488
|
getCanvasContext() {
|
|
@@ -1007,6 +1518,12 @@ or create a device with the 'debug: true' prop.`;
|
|
|
1007
1518
|
resetWebGL() {
|
|
1008
1519
|
throw new Error("not implemented");
|
|
1009
1520
|
}
|
|
1521
|
+
// INTERNAL LUMA.GL METHODS
|
|
1522
|
+
getModuleData(moduleName) {
|
|
1523
|
+
this._moduleData[moduleName] ||= {};
|
|
1524
|
+
return this._moduleData[moduleName];
|
|
1525
|
+
}
|
|
1526
|
+
// INTERNAL HELPERS
|
|
1010
1527
|
// IMPLEMENTATION
|
|
1011
1528
|
/** Helper to get the canvas context props */
|
|
1012
1529
|
static _getCanvasContextProps(props) {
|
|
@@ -1038,6 +1555,9 @@ or create a device with the 'debug: true' prop.`;
|
|
|
1038
1555
|
newProps.indexType = "uint32";
|
|
1039
1556
|
} else if (props.data instanceof Uint16Array) {
|
|
1040
1557
|
newProps.indexType = "uint16";
|
|
1558
|
+
} else if (props.data instanceof Uint8Array) {
|
|
1559
|
+
newProps.data = new Uint16Array(props.data);
|
|
1560
|
+
newProps.indexType = "uint16";
|
|
1041
1561
|
}
|
|
1042
1562
|
}
|
|
1043
1563
|
if (!newProps.indexType) {
|
|
@@ -1070,7 +1590,8 @@ __publicField(Device, "defaultProps", {
|
|
|
1070
1590
|
onVisibilityChange: (context) => log.log(1, `${context} Visibility changed ${context.isVisible}`)(),
|
|
1071
1591
|
onDevicePixelRatioChange: (context, info) => log.log(1, `${context} DPR changed ${info.oldRatio} => ${context.devicePixelRatio}`)(),
|
|
1072
1592
|
// Debug flags
|
|
1073
|
-
debug:
|
|
1593
|
+
debug: getDefaultDebugValue(),
|
|
1594
|
+
debugGPUTime: false,
|
|
1074
1595
|
debugShaders: log.get("debug-shaders") || void 0,
|
|
1075
1596
|
debugFramebuffers: Boolean(log.get("debug-framebuffers")),
|
|
1076
1597
|
debugFactories: Boolean(log.get("debug-factories")),
|
|
@@ -1081,9 +1602,11 @@ __publicField(Device, "defaultProps", {
|
|
|
1081
1602
|
// Experimental
|
|
1082
1603
|
_reuseDevices: false,
|
|
1083
1604
|
_requestMaxLimits: true,
|
|
1084
|
-
_cacheShaders:
|
|
1085
|
-
|
|
1086
|
-
|
|
1605
|
+
_cacheShaders: true,
|
|
1606
|
+
_destroyShaders: false,
|
|
1607
|
+
_cachePipelines: true,
|
|
1608
|
+
_sharePipelines: true,
|
|
1609
|
+
_destroyPipelines: false,
|
|
1087
1610
|
// TODO - Change these after confirming things work as expected
|
|
1088
1611
|
_initializeFeatures: true,
|
|
1089
1612
|
_disabledFeatures: {
|
|
@@ -1092,6 +1615,25 @@ __publicField(Device, "defaultProps", {
|
|
|
1092
1615
|
// INTERNAL
|
|
1093
1616
|
_handle: void 0
|
|
1094
1617
|
});
|
|
1618
|
+
function _getDefaultDebugValue(logDebugValue, nodeEnv) {
|
|
1619
|
+
if (logDebugValue !== void 0 && logDebugValue !== null) {
|
|
1620
|
+
return Boolean(logDebugValue);
|
|
1621
|
+
}
|
|
1622
|
+
if (nodeEnv !== void 0) {
|
|
1623
|
+
return nodeEnv !== "production";
|
|
1624
|
+
}
|
|
1625
|
+
return false;
|
|
1626
|
+
}
|
|
1627
|
+
function getDefaultDebugValue() {
|
|
1628
|
+
return _getDefaultDebugValue(log.get("debug"), getNodeEnv());
|
|
1629
|
+
}
|
|
1630
|
+
function getNodeEnv() {
|
|
1631
|
+
const processObject = globalThis.process;
|
|
1632
|
+
if (!(processObject == null ? void 0 : processObject.env)) {
|
|
1633
|
+
return void 0;
|
|
1634
|
+
}
|
|
1635
|
+
return processObject.env["NODE_ENV"];
|
|
1636
|
+
}
|
|
1095
1637
|
|
|
1096
1638
|
// dist/adapter/luma.js
|
|
1097
1639
|
var STARTUP_MESSAGE = "set luma.log.level=1 (or higher) to trace rendering";
|
|
@@ -1111,7 +1653,7 @@ var _Luma = class {
|
|
|
1111
1653
|
VERSION = (
|
|
1112
1654
|
// Version detection using build plugin
|
|
1113
1655
|
// @ts-expect-error no-undef
|
|
1114
|
-
true ? "9.
|
|
1656
|
+
true ? "9.3.0-alpha.10" : "running from source"
|
|
1115
1657
|
);
|
|
1116
1658
|
spector;
|
|
1117
1659
|
preregisteredAdapters = /* @__PURE__ */ new Map();
|
|
@@ -1276,9 +1818,91 @@ function getPageLoadPromise() {
|
|
|
1276
1818
|
return pageLoadPromise;
|
|
1277
1819
|
}
|
|
1278
1820
|
|
|
1279
|
-
// dist/adapter/canvas-
|
|
1821
|
+
// dist/adapter/canvas-surface.js
|
|
1280
1822
|
var import_env2 = require("@probe.gl/env");
|
|
1281
1823
|
|
|
1824
|
+
// dist/adapter/canvas-observer.js
|
|
1825
|
+
var CanvasObserver = class {
|
|
1826
|
+
props;
|
|
1827
|
+
_resizeObserver;
|
|
1828
|
+
_intersectionObserver;
|
|
1829
|
+
_observeDevicePixelRatioTimeout = null;
|
|
1830
|
+
_observeDevicePixelRatioMediaQuery = null;
|
|
1831
|
+
_handleDevicePixelRatioChange = () => this._refreshDevicePixelRatio();
|
|
1832
|
+
_trackPositionInterval = null;
|
|
1833
|
+
_started = false;
|
|
1834
|
+
get started() {
|
|
1835
|
+
return this._started;
|
|
1836
|
+
}
|
|
1837
|
+
constructor(props) {
|
|
1838
|
+
this.props = props;
|
|
1839
|
+
}
|
|
1840
|
+
start() {
|
|
1841
|
+
if (this._started || !this.props.canvas) {
|
|
1842
|
+
return;
|
|
1843
|
+
}
|
|
1844
|
+
this._started = true;
|
|
1845
|
+
this._intersectionObserver ||= new IntersectionObserver((entries) => this.props.onIntersection(entries));
|
|
1846
|
+
this._resizeObserver ||= new ResizeObserver((entries) => this.props.onResize(entries));
|
|
1847
|
+
this._intersectionObserver.observe(this.props.canvas);
|
|
1848
|
+
try {
|
|
1849
|
+
this._resizeObserver.observe(this.props.canvas, { box: "device-pixel-content-box" });
|
|
1850
|
+
} catch {
|
|
1851
|
+
this._resizeObserver.observe(this.props.canvas, { box: "content-box" });
|
|
1852
|
+
}
|
|
1853
|
+
this._observeDevicePixelRatioTimeout = setTimeout(() => this._refreshDevicePixelRatio(), 0);
|
|
1854
|
+
if (this.props.trackPosition) {
|
|
1855
|
+
this._trackPosition();
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
stop() {
|
|
1859
|
+
var _a, _b;
|
|
1860
|
+
if (!this._started) {
|
|
1861
|
+
return;
|
|
1862
|
+
}
|
|
1863
|
+
this._started = false;
|
|
1864
|
+
if (this._observeDevicePixelRatioTimeout) {
|
|
1865
|
+
clearTimeout(this._observeDevicePixelRatioTimeout);
|
|
1866
|
+
this._observeDevicePixelRatioTimeout = null;
|
|
1867
|
+
}
|
|
1868
|
+
if (this._observeDevicePixelRatioMediaQuery) {
|
|
1869
|
+
this._observeDevicePixelRatioMediaQuery.removeEventListener("change", this._handleDevicePixelRatioChange);
|
|
1870
|
+
this._observeDevicePixelRatioMediaQuery = null;
|
|
1871
|
+
}
|
|
1872
|
+
if (this._trackPositionInterval) {
|
|
1873
|
+
clearInterval(this._trackPositionInterval);
|
|
1874
|
+
this._trackPositionInterval = null;
|
|
1875
|
+
}
|
|
1876
|
+
(_a = this._resizeObserver) == null ? void 0 : _a.disconnect();
|
|
1877
|
+
(_b = this._intersectionObserver) == null ? void 0 : _b.disconnect();
|
|
1878
|
+
}
|
|
1879
|
+
_refreshDevicePixelRatio() {
|
|
1880
|
+
var _a;
|
|
1881
|
+
if (!this._started) {
|
|
1882
|
+
return;
|
|
1883
|
+
}
|
|
1884
|
+
this.props.onDevicePixelRatioChange();
|
|
1885
|
+
(_a = this._observeDevicePixelRatioMediaQuery) == null ? void 0 : _a.removeEventListener("change", this._handleDevicePixelRatioChange);
|
|
1886
|
+
this._observeDevicePixelRatioMediaQuery = matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
1887
|
+
this._observeDevicePixelRatioMediaQuery.addEventListener("change", this._handleDevicePixelRatioChange, { once: true });
|
|
1888
|
+
}
|
|
1889
|
+
_trackPosition(intervalMs = 100) {
|
|
1890
|
+
if (this._trackPositionInterval) {
|
|
1891
|
+
return;
|
|
1892
|
+
}
|
|
1893
|
+
this._trackPositionInterval = setInterval(() => {
|
|
1894
|
+
if (!this._started) {
|
|
1895
|
+
if (this._trackPositionInterval) {
|
|
1896
|
+
clearInterval(this._trackPositionInterval);
|
|
1897
|
+
this._trackPositionInterval = null;
|
|
1898
|
+
}
|
|
1899
|
+
} else {
|
|
1900
|
+
this.props.onPositionChange();
|
|
1901
|
+
}
|
|
1902
|
+
}, intervalMs);
|
|
1903
|
+
}
|
|
1904
|
+
};
|
|
1905
|
+
|
|
1282
1906
|
// dist/utils/promise-utils.js
|
|
1283
1907
|
function withResolvers() {
|
|
1284
1908
|
let resolve;
|
|
@@ -1290,8 +1914,22 @@ function withResolvers() {
|
|
|
1290
1914
|
return { promise, resolve, reject };
|
|
1291
1915
|
}
|
|
1292
1916
|
|
|
1293
|
-
// dist/
|
|
1294
|
-
|
|
1917
|
+
// dist/utils/assert.js
|
|
1918
|
+
function assert(condition, message) {
|
|
1919
|
+
var _a;
|
|
1920
|
+
if (!condition) {
|
|
1921
|
+
const error = new Error(message ?? "luma.gl assertion failed.");
|
|
1922
|
+
(_a = Error.captureStackTrace) == null ? void 0 : _a.call(Error, error, assert);
|
|
1923
|
+
throw error;
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
function assertDefined(value, message) {
|
|
1927
|
+
assert(value, message);
|
|
1928
|
+
return value;
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
// dist/adapter/canvas-surface.js
|
|
1932
|
+
var _CanvasSurface = class {
|
|
1295
1933
|
static isHTMLCanvas(canvas) {
|
|
1296
1934
|
return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
|
|
1297
1935
|
}
|
|
@@ -1325,17 +1963,21 @@ var _CanvasContext = class {
|
|
|
1325
1963
|
drawingBufferWidth;
|
|
1326
1964
|
/** Height of drawing buffer: automatically tracks this.pixelHeight if props.autoResize is true */
|
|
1327
1965
|
drawingBufferHeight;
|
|
1966
|
+
/** Resolves when the canvas is initialized, i.e. when the ResizeObserver has updated the pixel size */
|
|
1328
1967
|
_initializedResolvers = withResolvers();
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
_position;
|
|
1968
|
+
_canvasObserver;
|
|
1969
|
+
/** Position of the canvas in the document, updated by a timer */
|
|
1970
|
+
_position = [0, 0];
|
|
1971
|
+
/** Whether this canvas context has been destroyed */
|
|
1332
1972
|
destroyed = false;
|
|
1973
|
+
/** Whether the drawing buffer size needs to be resized (deferred resizing to avoid flicker) */
|
|
1974
|
+
_needsDrawingBufferResize = true;
|
|
1333
1975
|
toString() {
|
|
1334
1976
|
return `${this[Symbol.toStringTag]}(${this.id})`;
|
|
1335
1977
|
}
|
|
1336
1978
|
constructor(props) {
|
|
1337
1979
|
var _a, _b;
|
|
1338
|
-
this.props = { ...
|
|
1980
|
+
this.props = { ..._CanvasSurface.defaultProps, ...props };
|
|
1339
1981
|
props = this.props;
|
|
1340
1982
|
this.initialized = this._initializedResolvers.promise;
|
|
1341
1983
|
if (!(0, import_env2.isBrowser)()) {
|
|
@@ -1347,11 +1989,11 @@ var _CanvasContext = class {
|
|
|
1347
1989
|
} else {
|
|
1348
1990
|
this.canvas = props.canvas;
|
|
1349
1991
|
}
|
|
1350
|
-
if (
|
|
1992
|
+
if (_CanvasSurface.isHTMLCanvas(this.canvas)) {
|
|
1351
1993
|
this.id = props.id || this.canvas.id;
|
|
1352
1994
|
this.type = "html-canvas";
|
|
1353
1995
|
this.htmlCanvas = this.canvas;
|
|
1354
|
-
} else if (
|
|
1996
|
+
} else if (_CanvasSurface.isOffscreenCanvas(this.canvas)) {
|
|
1355
1997
|
this.id = props.id || "offscreen-canvas";
|
|
1356
1998
|
this.type = "offscreen-canvas";
|
|
1357
1999
|
this.offscreenCanvas = this.canvas;
|
|
@@ -1367,23 +2009,21 @@ var _CanvasContext = class {
|
|
|
1367
2009
|
this.drawingBufferHeight = this.canvas.height;
|
|
1368
2010
|
this.devicePixelRatio = globalThis.devicePixelRatio || 1;
|
|
1369
2011
|
this._position = [0, 0];
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
this.
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
}
|
|
1379
|
-
setTimeout(() => this._observeDevicePixelRatio(), 0);
|
|
1380
|
-
if (this.props.trackPosition) {
|
|
1381
|
-
this._trackPosition();
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
2012
|
+
this._canvasObserver = new CanvasObserver({
|
|
2013
|
+
canvas: this.htmlCanvas,
|
|
2014
|
+
trackPosition: this.props.trackPosition,
|
|
2015
|
+
onResize: (entries) => this._handleResize(entries),
|
|
2016
|
+
onIntersection: (entries) => this._handleIntersection(entries),
|
|
2017
|
+
onDevicePixelRatioChange: () => this._observeDevicePixelRatio(),
|
|
2018
|
+
onPositionChange: () => this.updatePosition()
|
|
2019
|
+
});
|
|
1384
2020
|
}
|
|
1385
2021
|
destroy() {
|
|
1386
|
-
this.destroyed
|
|
2022
|
+
if (!this.destroyed) {
|
|
2023
|
+
this.destroyed = true;
|
|
2024
|
+
this._stopObservers();
|
|
2025
|
+
this.device = null;
|
|
2026
|
+
}
|
|
1387
2027
|
}
|
|
1388
2028
|
setProps(props) {
|
|
1389
2029
|
if ("useDevicePixels" in props) {
|
|
@@ -1392,55 +2032,41 @@ var _CanvasContext = class {
|
|
|
1392
2032
|
}
|
|
1393
2033
|
return this;
|
|
1394
2034
|
}
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
*/
|
|
2035
|
+
/** Returns a framebuffer with properly resized current 'swap chain' textures */
|
|
2036
|
+
getCurrentFramebuffer(options) {
|
|
2037
|
+
this._resizeDrawingBufferIfNeeded();
|
|
2038
|
+
return this._getCurrentFramebuffer(options);
|
|
2039
|
+
}
|
|
1401
2040
|
getCSSSize() {
|
|
1402
2041
|
return [this.cssWidth, this.cssHeight];
|
|
1403
2042
|
}
|
|
1404
2043
|
getPosition() {
|
|
1405
2044
|
return this._position;
|
|
1406
2045
|
}
|
|
1407
|
-
/**
|
|
1408
|
-
* Returns the size covered by the canvas in actual device pixels.
|
|
1409
|
-
* @note This can be different from the 'CSS' size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
1410
|
-
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
1411
|
-
*/
|
|
1412
2046
|
getDevicePixelSize() {
|
|
1413
2047
|
return [this.devicePixelWidth, this.devicePixelHeight];
|
|
1414
2048
|
}
|
|
1415
|
-
/** Get the drawing buffer size (number of pixels GPU is rendering into, can be different from CSS size) */
|
|
1416
2049
|
getDrawingBufferSize() {
|
|
1417
2050
|
return [this.drawingBufferWidth, this.drawingBufferHeight];
|
|
1418
2051
|
}
|
|
1419
|
-
/** Returns the biggest allowed framebuffer size. @todo Allow the application to limit this? */
|
|
1420
2052
|
getMaxDrawingBufferSize() {
|
|
1421
2053
|
const maxTextureDimension = this.device.limits.maxTextureDimension2D;
|
|
1422
2054
|
return [maxTextureDimension, maxTextureDimension];
|
|
1423
2055
|
}
|
|
1424
|
-
/** Update the canvas drawing buffer size. Called automatically if props.autoResize is true. */
|
|
1425
2056
|
setDrawingBufferSize(width, height) {
|
|
1426
|
-
|
|
1427
|
-
|
|
2057
|
+
width = Math.floor(width);
|
|
2058
|
+
height = Math.floor(height);
|
|
2059
|
+
if (this.drawingBufferWidth === width && this.drawingBufferHeight === height) {
|
|
2060
|
+
return;
|
|
2061
|
+
}
|
|
1428
2062
|
this.drawingBufferWidth = width;
|
|
1429
2063
|
this.drawingBufferHeight = height;
|
|
2064
|
+
this._needsDrawingBufferResize = true;
|
|
1430
2065
|
}
|
|
1431
|
-
/**
|
|
1432
|
-
* Returns the current DPR (number of physical pixels per CSS pixel), if props.useDevicePixels is true
|
|
1433
|
-
* @note This can be a fractional (non-integer) number, e.g. when the user zooms in the browser.
|
|
1434
|
-
* @note This function handles the non-HTML canvas cases
|
|
1435
|
-
*/
|
|
1436
2066
|
getDevicePixelRatio() {
|
|
1437
|
-
const
|
|
1438
|
-
return
|
|
2067
|
+
const devicePixelRatio2 = typeof window !== "undefined" && window.devicePixelRatio;
|
|
2068
|
+
return devicePixelRatio2 || 1;
|
|
1439
2069
|
}
|
|
1440
|
-
// DEPRECATED METHODS
|
|
1441
|
-
/**
|
|
1442
|
-
* Maps CSS pixel position to device pixel position
|
|
1443
|
-
*/
|
|
1444
2070
|
cssToDevicePixels(cssPixel, yInvert = true) {
|
|
1445
2071
|
const ratio = this.cssToDeviceRatio();
|
|
1446
2072
|
const [width, height] = this.getDrawingBufferSize();
|
|
@@ -1450,10 +2076,10 @@ var _CanvasContext = class {
|
|
|
1450
2076
|
getPixelSize() {
|
|
1451
2077
|
return this.getDevicePixelSize();
|
|
1452
2078
|
}
|
|
1453
|
-
/** @deprecated
|
|
2079
|
+
/** @deprecated Use the current drawing buffer size for projection setup. */
|
|
1454
2080
|
getAspect() {
|
|
1455
|
-
const [width, height] = this.
|
|
1456
|
-
return width / height;
|
|
2081
|
+
const [width, height] = this.getDrawingBufferSize();
|
|
2082
|
+
return width > 0 && height > 0 ? width / height : 1;
|
|
1457
2083
|
}
|
|
1458
2084
|
/** @deprecated Returns multiplier need to convert CSS size to Device size */
|
|
1459
2085
|
cssToDeviceRatio() {
|
|
@@ -1469,19 +2095,41 @@ var _CanvasContext = class {
|
|
|
1469
2095
|
resize(size) {
|
|
1470
2096
|
this.setDrawingBufferSize(size.width, size.height);
|
|
1471
2097
|
}
|
|
1472
|
-
// IMPLEMENTATION
|
|
1473
|
-
/**
|
|
1474
|
-
* Allows subclass constructor to override the canvas id for auto created canvases.
|
|
1475
|
-
* This can really help when debugging DOM in apps that create multiple devices
|
|
1476
|
-
*/
|
|
1477
2098
|
_setAutoCreatedCanvasId(id) {
|
|
1478
2099
|
var _a;
|
|
1479
2100
|
if (((_a = this.htmlCanvas) == null ? void 0 : _a.id) === "lumagl-auto-created-canvas") {
|
|
1480
2101
|
this.htmlCanvas.id = id;
|
|
1481
2102
|
}
|
|
1482
2103
|
}
|
|
1483
|
-
/**
|
|
2104
|
+
/**
|
|
2105
|
+
* Starts DOM observation after the derived context and its device are fully initialized.
|
|
2106
|
+
*
|
|
2107
|
+
* `CanvasSurface` construction runs before subclasses can assign `this.device`, and the
|
|
2108
|
+
* default WebGL canvas context is created before `WebGLDevice` has initialized `limits`,
|
|
2109
|
+
* `features`, and the rest of its runtime state. Deferring observer startup avoids early
|
|
2110
|
+
* `ResizeObserver` and DPR callbacks running against a partially initialized device.
|
|
2111
|
+
*/
|
|
2112
|
+
_startObservers() {
|
|
2113
|
+
if (this.destroyed) {
|
|
2114
|
+
return;
|
|
2115
|
+
}
|
|
2116
|
+
this._canvasObserver.start();
|
|
2117
|
+
}
|
|
2118
|
+
/**
|
|
2119
|
+
* Stops all DOM observation and timers associated with a canvas surface.
|
|
2120
|
+
*
|
|
2121
|
+
* This pairs with `_startObservers()` so teardown uses the same lifecycle whether a context is
|
|
2122
|
+
* explicitly destroyed, abandoned during device reuse, or temporarily has not started observing
|
|
2123
|
+
* yet. Centralizing shutdown here keeps resize/DPR/position watchers from surviving past the
|
|
2124
|
+
* lifetime of the owning device.
|
|
2125
|
+
*/
|
|
2126
|
+
_stopObservers() {
|
|
2127
|
+
this._canvasObserver.stop();
|
|
2128
|
+
}
|
|
1484
2129
|
_handleIntersection(entries) {
|
|
2130
|
+
if (this.destroyed) {
|
|
2131
|
+
return;
|
|
2132
|
+
}
|
|
1485
2133
|
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
1486
2134
|
if (!entry) {
|
|
1487
2135
|
return;
|
|
@@ -1492,22 +2140,21 @@ var _CanvasContext = class {
|
|
|
1492
2140
|
this.device.props.onVisibilityChange(this);
|
|
1493
2141
|
}
|
|
1494
2142
|
}
|
|
1495
|
-
/**
|
|
1496
|
-
* Reacts to an observed resize by using the most accurate pixel size information the browser can provide
|
|
1497
|
-
* @see https://web.dev/articles/device-pixel-content-box
|
|
1498
|
-
* @see https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html
|
|
1499
|
-
*/
|
|
1500
2143
|
_handleResize(entries) {
|
|
1501
|
-
var _a, _b;
|
|
2144
|
+
var _a, _b, _c, _d, _e;
|
|
2145
|
+
if (this.destroyed) {
|
|
2146
|
+
return;
|
|
2147
|
+
}
|
|
1502
2148
|
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
1503
2149
|
if (!entry) {
|
|
1504
2150
|
return;
|
|
1505
2151
|
}
|
|
1506
|
-
|
|
1507
|
-
this.
|
|
2152
|
+
const contentBoxSize = assertDefined((_a = entry.contentBoxSize) == null ? void 0 : _a[0]);
|
|
2153
|
+
this.cssWidth = contentBoxSize.inlineSize;
|
|
2154
|
+
this.cssHeight = contentBoxSize.blockSize;
|
|
1508
2155
|
const oldPixelSize = this.getDevicePixelSize();
|
|
1509
|
-
const devicePixelWidth = ((
|
|
1510
|
-
const devicePixelHeight = ((
|
|
2156
|
+
const devicePixelWidth = ((_c = (_b = entry.devicePixelContentBoxSize) == null ? void 0 : _b[0]) == null ? void 0 : _c.inlineSize) || contentBoxSize.inlineSize * devicePixelRatio;
|
|
2157
|
+
const devicePixelHeight = ((_e = (_d = entry.devicePixelContentBoxSize) == null ? void 0 : _d[0]) == null ? void 0 : _e.blockSize) || contentBoxSize.blockSize * devicePixelRatio;
|
|
1511
2158
|
const [maxDevicePixelWidth, maxDevicePixelHeight] = this.getMaxDrawingBufferSize();
|
|
1512
2159
|
this.devicePixelWidth = Math.max(1, Math.min(devicePixelWidth, maxDevicePixelWidth));
|
|
1513
2160
|
this.devicePixelHeight = Math.max(1, Math.min(devicePixelHeight, maxDevicePixelHeight));
|
|
@@ -1517,44 +2164,46 @@ var _CanvasContext = class {
|
|
|
1517
2164
|
_updateDrawingBufferSize() {
|
|
1518
2165
|
if (this.props.autoResize) {
|
|
1519
2166
|
if (typeof this.props.useDevicePixels === "number") {
|
|
1520
|
-
const
|
|
1521
|
-
this.setDrawingBufferSize(this.cssWidth *
|
|
2167
|
+
const devicePixelRatio2 = this.props.useDevicePixels;
|
|
2168
|
+
this.setDrawingBufferSize(this.cssWidth * devicePixelRatio2, this.cssHeight * devicePixelRatio2);
|
|
1522
2169
|
} else if (this.props.useDevicePixels) {
|
|
1523
2170
|
this.setDrawingBufferSize(this.devicePixelWidth, this.devicePixelHeight);
|
|
1524
2171
|
} else {
|
|
1525
2172
|
this.setDrawingBufferSize(this.cssWidth, this.cssHeight);
|
|
1526
2173
|
}
|
|
1527
|
-
this._updateDevice();
|
|
1528
2174
|
}
|
|
1529
2175
|
this._initializedResolvers.resolve();
|
|
1530
2176
|
this.isInitialized = true;
|
|
1531
2177
|
this.updatePosition();
|
|
1532
2178
|
}
|
|
1533
|
-
|
|
2179
|
+
_resizeDrawingBufferIfNeeded() {
|
|
2180
|
+
if (this._needsDrawingBufferResize) {
|
|
2181
|
+
this._needsDrawingBufferResize = false;
|
|
2182
|
+
const sizeChanged = this.drawingBufferWidth !== this.canvas.width || this.drawingBufferHeight !== this.canvas.height;
|
|
2183
|
+
if (sizeChanged) {
|
|
2184
|
+
this.canvas.width = this.drawingBufferWidth;
|
|
2185
|
+
this.canvas.height = this.drawingBufferHeight;
|
|
2186
|
+
this._configureDevice();
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
1534
2190
|
_observeDevicePixelRatio() {
|
|
2191
|
+
var _a, _b;
|
|
2192
|
+
if (this.destroyed || !this._canvasObserver.started) {
|
|
2193
|
+
return;
|
|
2194
|
+
}
|
|
1535
2195
|
const oldRatio = this.devicePixelRatio;
|
|
1536
2196
|
this.devicePixelRatio = window.devicePixelRatio;
|
|
1537
2197
|
this.updatePosition();
|
|
1538
|
-
this.device.props.onDevicePixelRatioChange(this, {
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
/** Start tracking positions with a timer */
|
|
1542
|
-
_trackPosition(intervalMs = 100) {
|
|
1543
|
-
const intervalId = setInterval(() => {
|
|
1544
|
-
if (this.destroyed) {
|
|
1545
|
-
clearInterval(intervalId);
|
|
1546
|
-
} else {
|
|
1547
|
-
this.updatePosition();
|
|
1548
|
-
}
|
|
1549
|
-
}, intervalMs);
|
|
2198
|
+
(_b = (_a = this.device.props).onDevicePixelRatioChange) == null ? void 0 : _b.call(_a, this, {
|
|
2199
|
+
oldRatio
|
|
2200
|
+
});
|
|
1550
2201
|
}
|
|
1551
|
-
/**
|
|
1552
|
-
* Calculated the absolute position of the canvas
|
|
1553
|
-
* @note - getBoundingClientRect() is normally cheap but can be expensive
|
|
1554
|
-
* if called before browser has finished a reflow. Should not be the case here.
|
|
1555
|
-
*/
|
|
1556
2202
|
updatePosition() {
|
|
1557
2203
|
var _a, _b, _c;
|
|
2204
|
+
if (this.destroyed) {
|
|
2205
|
+
return;
|
|
2206
|
+
}
|
|
1558
2207
|
const newRect = (_a = this.htmlCanvas) == null ? void 0 : _a.getBoundingClientRect();
|
|
1559
2208
|
if (newRect) {
|
|
1560
2209
|
const position = [newRect.left, newRect.top];
|
|
@@ -1563,13 +2212,15 @@ var _CanvasContext = class {
|
|
|
1563
2212
|
if (positionChanged) {
|
|
1564
2213
|
const oldPosition = this._position;
|
|
1565
2214
|
this._position = position;
|
|
1566
|
-
(_c = (_b = this.device.props).onPositionChange) == null ? void 0 : _c.call(_b, this, {
|
|
2215
|
+
(_c = (_b = this.device.props).onPositionChange) == null ? void 0 : _c.call(_b, this, {
|
|
2216
|
+
oldPosition
|
|
2217
|
+
});
|
|
1567
2218
|
}
|
|
1568
2219
|
}
|
|
1569
2220
|
}
|
|
1570
2221
|
};
|
|
1571
|
-
var
|
|
1572
|
-
__publicField(
|
|
2222
|
+
var CanvasSurface = _CanvasSurface;
|
|
2223
|
+
__publicField(CanvasSurface, "defaultProps", {
|
|
1573
2224
|
id: void 0,
|
|
1574
2225
|
canvas: null,
|
|
1575
2226
|
width: 800,
|
|
@@ -1597,7 +2248,7 @@ function getContainer(container) {
|
|
|
1597
2248
|
}
|
|
1598
2249
|
function getCanvasFromDOM(canvasId) {
|
|
1599
2250
|
const canvas = document.getElementById(canvasId);
|
|
1600
|
-
if (!
|
|
2251
|
+
if (!CanvasSurface.isHTMLCanvas(canvas)) {
|
|
1601
2252
|
throw new Error("Object is not a canvas element");
|
|
1602
2253
|
}
|
|
1603
2254
|
return canvas;
|
|
@@ -1621,33 +2272,40 @@ function scalePixels(pixel, ratio, width, height, yInvert) {
|
|
|
1621
2272
|
const point = pixel;
|
|
1622
2273
|
const x = scaleX(point[0], ratio, width);
|
|
1623
2274
|
let y = scaleY(point[1], ratio, height, yInvert);
|
|
1624
|
-
let
|
|
1625
|
-
const xHigh =
|
|
1626
|
-
|
|
2275
|
+
let temporary = scaleX(point[0] + 1, ratio, width);
|
|
2276
|
+
const xHigh = temporary === width - 1 ? temporary : temporary - 1;
|
|
2277
|
+
temporary = scaleY(point[1] + 1, ratio, height, yInvert);
|
|
1627
2278
|
let yHigh;
|
|
1628
2279
|
if (yInvert) {
|
|
1629
|
-
|
|
2280
|
+
temporary = temporary === 0 ? temporary : temporary + 1;
|
|
1630
2281
|
yHigh = y;
|
|
1631
|
-
y =
|
|
2282
|
+
y = temporary;
|
|
1632
2283
|
} else {
|
|
1633
|
-
yHigh =
|
|
2284
|
+
yHigh = temporary === height - 1 ? temporary : temporary - 1;
|
|
1634
2285
|
}
|
|
1635
2286
|
return {
|
|
1636
2287
|
x,
|
|
1637
2288
|
y,
|
|
1638
|
-
// when ratio < 1, current css pixel and next css pixel may point to same device pixel, set width/height to 1 in those cases.
|
|
1639
2289
|
width: Math.max(xHigh - x + 1, 1),
|
|
1640
2290
|
height: Math.max(yHigh - y + 1, 1)
|
|
1641
2291
|
};
|
|
1642
2292
|
}
|
|
1643
2293
|
function scaleX(x, ratio, width) {
|
|
1644
|
-
|
|
1645
|
-
return r;
|
|
2294
|
+
return Math.min(Math.round(x * ratio), width - 1);
|
|
1646
2295
|
}
|
|
1647
2296
|
function scaleY(y, ratio, height, yInvert) {
|
|
1648
2297
|
return yInvert ? Math.max(0, height - 1 - Math.round(y * ratio)) : Math.min(Math.round(y * ratio), height - 1);
|
|
1649
2298
|
}
|
|
1650
2299
|
|
|
2300
|
+
// dist/adapter/canvas-context.js
|
|
2301
|
+
var CanvasContext = class extends CanvasSurface {
|
|
2302
|
+
};
|
|
2303
|
+
__publicField(CanvasContext, "defaultProps", CanvasSurface.defaultProps);
|
|
2304
|
+
|
|
2305
|
+
// dist/adapter/presentation-context.js
|
|
2306
|
+
var PresentationContext = class extends CanvasSurface {
|
|
2307
|
+
};
|
|
2308
|
+
|
|
1651
2309
|
// dist/adapter/resources/sampler.js
|
|
1652
2310
|
var _Sampler = class extends Resource {
|
|
1653
2311
|
get [Symbol.toStringTag]() {
|
|
@@ -1702,7 +2360,15 @@ var _Texture = class extends Resource {
|
|
|
1702
2360
|
depth;
|
|
1703
2361
|
/** mip levels in this texture */
|
|
1704
2362
|
mipLevels;
|
|
1705
|
-
/**
|
|
2363
|
+
/** sample count */
|
|
2364
|
+
samples;
|
|
2365
|
+
/** Rows are multiples of this length, padded with extra bytes if needed */
|
|
2366
|
+
byteAlignment;
|
|
2367
|
+
/** The ready promise is always resolved. It is provided for type compatibility with DynamicTexture. */
|
|
2368
|
+
ready = Promise.resolve(this);
|
|
2369
|
+
/** isReady is always true. It is provided for type compatibility with DynamicTexture. */
|
|
2370
|
+
isReady = true;
|
|
2371
|
+
/** "Time" of last update. Monotonically increasing timestamp. TODO move to DynamicTexture? */
|
|
1706
2372
|
updateTimestamp;
|
|
1707
2373
|
get [Symbol.toStringTag]() {
|
|
1708
2374
|
return "Texture";
|
|
@@ -1711,7 +2377,7 @@ var _Texture = class extends Resource {
|
|
|
1711
2377
|
return `Texture(${this.id},${this.format},${this.width}x${this.height})`;
|
|
1712
2378
|
}
|
|
1713
2379
|
/** Do not use directly. Create with device.createTexture() */
|
|
1714
|
-
constructor(device, props) {
|
|
2380
|
+
constructor(device, props, backendProps) {
|
|
1715
2381
|
props = _Texture.normalizeProps(device, props);
|
|
1716
2382
|
super(device, props, _Texture.defaultProps);
|
|
1717
2383
|
this.dimension = this.props.dimension;
|
|
@@ -1721,6 +2387,10 @@ var _Texture = class extends Resource {
|
|
|
1721
2387
|
this.height = this.props.height;
|
|
1722
2388
|
this.depth = this.props.depth;
|
|
1723
2389
|
this.mipLevels = this.props.mipLevels;
|
|
2390
|
+
this.samples = this.props.samples || 1;
|
|
2391
|
+
if (this.dimension === "cube") {
|
|
2392
|
+
this.depth = 6;
|
|
2393
|
+
}
|
|
1724
2394
|
if (this.props.width === void 0 || this.props.height === void 0) {
|
|
1725
2395
|
if (device.isExternalImage(props.data)) {
|
|
1726
2396
|
const size = device.getExternalImageSize(props.data);
|
|
@@ -1730,16 +2400,13 @@ var _Texture = class extends Resource {
|
|
|
1730
2400
|
this.width = 1;
|
|
1731
2401
|
this.height = 1;
|
|
1732
2402
|
if (this.props.width === void 0 || this.props.height === void 0) {
|
|
1733
|
-
log.warn(`${this} created with undefined width or height. This is deprecated. Use
|
|
2403
|
+
log.warn(`${this} created with undefined width or height. This is deprecated. Use DynamicTexture instead.`)();
|
|
1734
2404
|
}
|
|
1735
2405
|
}
|
|
1736
2406
|
}
|
|
2407
|
+
this.byteAlignment = (backendProps == null ? void 0 : backendProps.byteAlignment) || 1;
|
|
1737
2408
|
this.updateTimestamp = device.incrementTimestamp();
|
|
1738
2409
|
}
|
|
1739
|
-
/** Set sampler props associated with this texture */
|
|
1740
|
-
setSampler(sampler) {
|
|
1741
|
-
this.sampler = sampler instanceof Sampler ? sampler : this.device.createSampler(sampler);
|
|
1742
|
-
}
|
|
1743
2410
|
/**
|
|
1744
2411
|
* Create a new texture with the same parameters and optionally a different size
|
|
1745
2412
|
* @note Textures are immutable and cannot be resized after creation, but we can create a similar texture with the same parameters but a new size.
|
|
@@ -1748,6 +2415,105 @@ var _Texture = class extends Resource {
|
|
|
1748
2415
|
clone(size) {
|
|
1749
2416
|
return this.device.createTexture({ ...this.props, ...size });
|
|
1750
2417
|
}
|
|
2418
|
+
/** Set sampler props associated with this texture */
|
|
2419
|
+
setSampler(sampler) {
|
|
2420
|
+
this.sampler = sampler instanceof Sampler ? sampler : this.device.createSampler(sampler);
|
|
2421
|
+
}
|
|
2422
|
+
/**
|
|
2423
|
+
* Copy raw image data (bytes) into the texture.
|
|
2424
|
+
*
|
|
2425
|
+
* @note Deprecated compatibility wrapper over {@link writeData}.
|
|
2426
|
+
* @note Uses the same layout defaults and alignment rules as {@link writeData}.
|
|
2427
|
+
* @note Tightly packed CPU uploads can omit `bytesPerRow` and `rowsPerImage`.
|
|
2428
|
+
* @note If the CPU source rows are padded, pass explicit `bytesPerRow` and `rowsPerImage`.
|
|
2429
|
+
* @deprecated Use writeData()
|
|
2430
|
+
*/
|
|
2431
|
+
copyImageData(options) {
|
|
2432
|
+
const { data, depth, ...writeOptions } = options;
|
|
2433
|
+
this.writeData(data, {
|
|
2434
|
+
...writeOptions,
|
|
2435
|
+
depthOrArrayLayers: writeOptions.depthOrArrayLayers ?? depth
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
2438
|
+
/**
|
|
2439
|
+
* Calculates the memory layout of the texture, required when reading and writing data.
|
|
2440
|
+
* @return the backend-aligned linear layout, in particular bytesPerRow which includes any required padding for buffer copy/read paths
|
|
2441
|
+
*/
|
|
2442
|
+
computeMemoryLayout(options_ = {}) {
|
|
2443
|
+
const options = this._normalizeTextureReadOptions(options_);
|
|
2444
|
+
const { width = this.width, height = this.height, depthOrArrayLayers = this.depth } = options;
|
|
2445
|
+
const { format, byteAlignment } = this;
|
|
2446
|
+
return textureFormatDecoder.computeMemoryLayout({
|
|
2447
|
+
format,
|
|
2448
|
+
width,
|
|
2449
|
+
height,
|
|
2450
|
+
depth: depthOrArrayLayers,
|
|
2451
|
+
byteAlignment
|
|
2452
|
+
});
|
|
2453
|
+
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Read the contents of a texture into a GPU Buffer.
|
|
2456
|
+
* @returns A Buffer containing the texture data.
|
|
2457
|
+
*
|
|
2458
|
+
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
2459
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the backend-aligned layout.
|
|
2460
|
+
* @note The application can call Buffer.readAsync() to read the returned buffer on the CPU.
|
|
2461
|
+
* @note The destination buffer must be supplied by the caller and must be large enough for the requested region.
|
|
2462
|
+
* @note On WebGPU this corresponds to a texture-to-buffer copy and uses buffer-copy alignment rules.
|
|
2463
|
+
* @note On WebGL, luma.gl emulates the same logical readback behavior.
|
|
2464
|
+
*/
|
|
2465
|
+
readBuffer(options, buffer) {
|
|
2466
|
+
throw new Error("readBuffer not implemented");
|
|
2467
|
+
}
|
|
2468
|
+
/**
|
|
2469
|
+
* Reads data from a texture into an ArrayBuffer.
|
|
2470
|
+
* @returns An ArrayBuffer containing the texture data.
|
|
2471
|
+
*
|
|
2472
|
+
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
2473
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
2474
|
+
* @deprecated Use Texture.readBuffer() with an explicit destination buffer, or DynamicTexture.readAsync() for convenience readback.
|
|
2475
|
+
*/
|
|
2476
|
+
readDataAsync(options) {
|
|
2477
|
+
throw new Error("readBuffer not implemented");
|
|
2478
|
+
}
|
|
2479
|
+
/**
|
|
2480
|
+
* Writes a GPU Buffer into a texture.
|
|
2481
|
+
*
|
|
2482
|
+
* @param buffer - Source GPU buffer.
|
|
2483
|
+
* @param options - Destination subresource, extent, and source layout options.
|
|
2484
|
+
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
2485
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the backend-aligned layout.
|
|
2486
|
+
* @note On WebGPU this corresponds to a buffer-to-texture copy and uses buffer-copy alignment rules.
|
|
2487
|
+
* @note On WebGL, luma.gl emulates the same destination and layout semantics.
|
|
2488
|
+
*/
|
|
2489
|
+
writeBuffer(buffer, options) {
|
|
2490
|
+
throw new Error("readBuffer not implemented");
|
|
2491
|
+
}
|
|
2492
|
+
/**
|
|
2493
|
+
* Writes an array buffer into a texture.
|
|
2494
|
+
*
|
|
2495
|
+
* @param data - Source texel data.
|
|
2496
|
+
* @param options - Destination subresource, extent, and source layout options.
|
|
2497
|
+
* @note If `bytesPerRow` and `rowsPerImage` are omitted, luma.gl computes a tightly packed CPU-memory layout for the requested region.
|
|
2498
|
+
* @note On WebGPU this corresponds to `GPUQueue.writeTexture()` and does not implicitly pad rows to 256 bytes.
|
|
2499
|
+
* @note On WebGL, padded CPU data is supported via the same `bytesPerRow` and `rowsPerImage` options.
|
|
2500
|
+
*/
|
|
2501
|
+
writeData(data, options) {
|
|
2502
|
+
throw new Error("readBuffer not implemented");
|
|
2503
|
+
}
|
|
2504
|
+
// IMPLEMENTATION SPECIFIC
|
|
2505
|
+
/**
|
|
2506
|
+
* WebGL can read data synchronously.
|
|
2507
|
+
* @note While it is convenient, the performance penalty is very significant
|
|
2508
|
+
*/
|
|
2509
|
+
readDataSyncWebGL(options) {
|
|
2510
|
+
throw new Error("readDataSyncWebGL not available");
|
|
2511
|
+
}
|
|
2512
|
+
/** Generate mipmaps (WebGL only) */
|
|
2513
|
+
generateMipmapsWebGL() {
|
|
2514
|
+
throw new Error("generateMipmapsWebGL not available");
|
|
2515
|
+
}
|
|
2516
|
+
// HELPERS
|
|
1751
2517
|
/** Ensure we have integer coordinates */
|
|
1752
2518
|
static normalizeProps(device, props) {
|
|
1753
2519
|
const newProps = { ...props };
|
|
@@ -1760,7 +2526,6 @@ var _Texture = class extends Resource {
|
|
|
1760
2526
|
}
|
|
1761
2527
|
return newProps;
|
|
1762
2528
|
}
|
|
1763
|
-
// HELPERS
|
|
1764
2529
|
/** Initialize texture with supplied props */
|
|
1765
2530
|
// eslint-disable-next-line max-statements
|
|
1766
2531
|
_initializeData(data) {
|
|
@@ -1794,23 +2559,148 @@ var _Texture = class extends Resource {
|
|
|
1794
2559
|
}
|
|
1795
2560
|
}
|
|
1796
2561
|
_normalizeCopyImageDataOptions(options_) {
|
|
1797
|
-
const {
|
|
1798
|
-
const options = {
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
}
|
|
1803
|
-
options.bytesPerRow = options_.bytesPerRow || width * (info.bytesPerPixel || 4);
|
|
1804
|
-
options.rowsPerImage = options_.rowsPerImage || height;
|
|
1805
|
-
return options;
|
|
2562
|
+
const { data, depth, ...writeOptions } = options_;
|
|
2563
|
+
const options = this._normalizeTextureWriteOptions({
|
|
2564
|
+
...writeOptions,
|
|
2565
|
+
depthOrArrayLayers: writeOptions.depthOrArrayLayers ?? depth
|
|
2566
|
+
});
|
|
2567
|
+
return { data, depth: options.depthOrArrayLayers, ...options };
|
|
1806
2568
|
}
|
|
1807
2569
|
_normalizeCopyExternalImageOptions(options_) {
|
|
2570
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2571
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2572
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
1808
2573
|
const size = this.device.getExternalImageSize(options_.image);
|
|
1809
|
-
const options = {
|
|
1810
|
-
|
|
1811
|
-
|
|
2574
|
+
const options = {
|
|
2575
|
+
..._Texture.defaultCopyExternalImageOptions,
|
|
2576
|
+
...mipLevelSize,
|
|
2577
|
+
...size,
|
|
2578
|
+
...optionsWithoutUndefined
|
|
2579
|
+
};
|
|
2580
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2581
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2582
|
+
options.depth = Math.min(options.depth, mipLevelSize.depthOrArrayLayers - options.z);
|
|
2583
|
+
return options;
|
|
2584
|
+
}
|
|
2585
|
+
_normalizeTextureReadOptions(options_) {
|
|
2586
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2587
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2588
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
2589
|
+
const options = {
|
|
2590
|
+
..._Texture.defaultTextureReadOptions,
|
|
2591
|
+
...mipLevelSize,
|
|
2592
|
+
...optionsWithoutUndefined
|
|
2593
|
+
};
|
|
2594
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2595
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2596
|
+
options.depthOrArrayLayers = Math.min(options.depthOrArrayLayers, mipLevelSize.depthOrArrayLayers - options.z);
|
|
2597
|
+
return options;
|
|
2598
|
+
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Normalizes a texture read request and validates the color-only readback contract used by the
|
|
2601
|
+
* current texture read APIs. Supported dimensions are `2d`, `cube`, `cube-array`,
|
|
2602
|
+
* `2d-array`, and `3d`.
|
|
2603
|
+
*
|
|
2604
|
+
* @throws if the texture format, aspect, or dimension is not supported by the first-pass
|
|
2605
|
+
* color-read implementation.
|
|
2606
|
+
*/
|
|
2607
|
+
_getSupportedColorReadOptions(options_) {
|
|
2608
|
+
const options = this._normalizeTextureReadOptions(options_);
|
|
2609
|
+
const formatInfo = textureFormatDecoder.getInfo(this.format);
|
|
2610
|
+
this._validateColorReadAspect(options);
|
|
2611
|
+
this._validateColorReadFormat(formatInfo);
|
|
2612
|
+
switch (this.dimension) {
|
|
2613
|
+
case "2d":
|
|
2614
|
+
case "cube":
|
|
2615
|
+
case "cube-array":
|
|
2616
|
+
case "2d-array":
|
|
2617
|
+
case "3d":
|
|
2618
|
+
return options;
|
|
2619
|
+
default:
|
|
2620
|
+
throw new Error(`${this} color readback does not support ${this.dimension} textures`);
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
/** Validates that a read request targets the full color aspect of the texture. */
|
|
2624
|
+
_validateColorReadAspect(options) {
|
|
2625
|
+
if (options.aspect !== "all") {
|
|
2626
|
+
throw new Error(`${this} color readback only supports aspect 'all'`);
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
/** Validates that a read request targets an uncompressed color-renderable texture format. */
|
|
2630
|
+
_validateColorReadFormat(formatInfo) {
|
|
2631
|
+
if (formatInfo.compressed) {
|
|
2632
|
+
throw new Error(`${this} color readback does not support compressed formats (${this.format})`);
|
|
2633
|
+
}
|
|
2634
|
+
switch (formatInfo.attachment) {
|
|
2635
|
+
case "color":
|
|
2636
|
+
return;
|
|
2637
|
+
case "depth":
|
|
2638
|
+
throw new Error(`${this} color readback does not support depth formats (${this.format})`);
|
|
2639
|
+
case "stencil":
|
|
2640
|
+
throw new Error(`${this} color readback does not support stencil formats (${this.format})`);
|
|
2641
|
+
case "depth-stencil":
|
|
2642
|
+
throw new Error(`${this} color readback does not support depth-stencil formats (${this.format})`);
|
|
2643
|
+
default:
|
|
2644
|
+
throw new Error(`${this} color readback does not support format ${this.format}`);
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
_normalizeTextureWriteOptions(options_) {
|
|
2648
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2649
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2650
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
2651
|
+
const options = {
|
|
2652
|
+
..._Texture.defaultTextureWriteOptions,
|
|
2653
|
+
...mipLevelSize,
|
|
2654
|
+
...optionsWithoutUndefined
|
|
2655
|
+
};
|
|
2656
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2657
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2658
|
+
options.depthOrArrayLayers = Math.min(options.depthOrArrayLayers, mipLevelSize.depthOrArrayLayers - options.z);
|
|
2659
|
+
const layout = textureFormatDecoder.computeMemoryLayout({
|
|
2660
|
+
format: this.format,
|
|
2661
|
+
width: options.width,
|
|
2662
|
+
height: options.height,
|
|
2663
|
+
depth: options.depthOrArrayLayers,
|
|
2664
|
+
byteAlignment: this.byteAlignment
|
|
2665
|
+
});
|
|
2666
|
+
const minimumBytesPerRow = layout.bytesPerPixel * options.width;
|
|
2667
|
+
options.bytesPerRow = optionsWithoutUndefined.bytesPerRow ?? layout.bytesPerRow;
|
|
2668
|
+
options.rowsPerImage = optionsWithoutUndefined.rowsPerImage ?? options.height;
|
|
2669
|
+
if (options.bytesPerRow < minimumBytesPerRow) {
|
|
2670
|
+
throw new Error(`bytesPerRow (${options.bytesPerRow}) must be at least ${minimumBytesPerRow} for ${this.format}`);
|
|
2671
|
+
}
|
|
2672
|
+
if (options.rowsPerImage < options.height) {
|
|
2673
|
+
throw new Error(`rowsPerImage (${options.rowsPerImage}) must be at least ${options.height} for ${this.format}`);
|
|
2674
|
+
}
|
|
2675
|
+
const bytesPerPixel = this.device.getTextureFormatInfo(this.format).bytesPerPixel;
|
|
2676
|
+
if (bytesPerPixel && options.bytesPerRow % bytesPerPixel !== 0) {
|
|
2677
|
+
throw new Error(`bytesPerRow (${options.bytesPerRow}) must be a multiple of bytesPerPixel (${bytesPerPixel}) for ${this.format}`);
|
|
2678
|
+
}
|
|
1812
2679
|
return options;
|
|
1813
2680
|
}
|
|
2681
|
+
_getMipLevelSize(mipLevel) {
|
|
2682
|
+
const width = Math.max(1, this.width >> mipLevel);
|
|
2683
|
+
const height = this.baseDimension === "1d" ? 1 : Math.max(1, this.height >> mipLevel);
|
|
2684
|
+
const depthOrArrayLayers = this.dimension === "3d" ? Math.max(1, this.depth >> mipLevel) : this.depth;
|
|
2685
|
+
return { width, height, depthOrArrayLayers };
|
|
2686
|
+
}
|
|
2687
|
+
getAllocatedByteLength() {
|
|
2688
|
+
let allocatedByteLength = 0;
|
|
2689
|
+
for (let mipLevel = 0; mipLevel < this.mipLevels; mipLevel++) {
|
|
2690
|
+
const { width, height, depthOrArrayLayers } = this._getMipLevelSize(mipLevel);
|
|
2691
|
+
allocatedByteLength += textureFormatDecoder.computeMemoryLayout({
|
|
2692
|
+
format: this.format,
|
|
2693
|
+
width,
|
|
2694
|
+
height,
|
|
2695
|
+
depth: depthOrArrayLayers,
|
|
2696
|
+
byteAlignment: 1
|
|
2697
|
+
}).byteLength;
|
|
2698
|
+
}
|
|
2699
|
+
return allocatedByteLength * this.samples;
|
|
2700
|
+
}
|
|
2701
|
+
static _omitUndefined(options) {
|
|
2702
|
+
return Object.fromEntries(Object.entries(options).filter(([, value]) => value !== void 0));
|
|
2703
|
+
}
|
|
1814
2704
|
};
|
|
1815
2705
|
var Texture = _Texture;
|
|
1816
2706
|
/** The texture can be bound for use as a sampled texture in a shader */
|
|
@@ -1827,13 +2717,12 @@ __publicField(Texture, "COPY_DST", 2);
|
|
|
1827
2717
|
__publicField(Texture, "TEXTURE", 4);
|
|
1828
2718
|
/** @deprecated Use Texture.RENDER */
|
|
1829
2719
|
__publicField(Texture, "RENDER_ATTACHMENT", 16);
|
|
1830
|
-
/** Default options */
|
|
1831
2720
|
__publicField(Texture, "defaultProps", {
|
|
1832
2721
|
...Resource.defaultProps,
|
|
1833
2722
|
data: null,
|
|
1834
2723
|
dimension: "2d",
|
|
1835
2724
|
format: "rgba8unorm",
|
|
1836
|
-
usage: _Texture.
|
|
2725
|
+
usage: _Texture.SAMPLE | _Texture.RENDER | _Texture.COPY_DST,
|
|
1837
2726
|
width: void 0,
|
|
1838
2727
|
height: void 0,
|
|
1839
2728
|
depth: 1,
|
|
@@ -1847,6 +2736,10 @@ __publicField(Texture, "defaultCopyDataOptions", {
|
|
|
1847
2736
|
byteOffset: 0,
|
|
1848
2737
|
bytesPerRow: void 0,
|
|
1849
2738
|
rowsPerImage: void 0,
|
|
2739
|
+
width: void 0,
|
|
2740
|
+
height: void 0,
|
|
2741
|
+
depthOrArrayLayers: void 0,
|
|
2742
|
+
depth: 1,
|
|
1850
2743
|
mipLevel: 0,
|
|
1851
2744
|
x: 0,
|
|
1852
2745
|
y: 0,
|
|
@@ -1870,6 +2763,29 @@ __publicField(Texture, "defaultCopyExternalImageOptions", {
|
|
|
1870
2763
|
premultipliedAlpha: false,
|
|
1871
2764
|
flipY: false
|
|
1872
2765
|
});
|
|
2766
|
+
__publicField(Texture, "defaultTextureReadOptions", {
|
|
2767
|
+
x: 0,
|
|
2768
|
+
y: 0,
|
|
2769
|
+
z: 0,
|
|
2770
|
+
width: void 0,
|
|
2771
|
+
height: void 0,
|
|
2772
|
+
depthOrArrayLayers: 1,
|
|
2773
|
+
mipLevel: 0,
|
|
2774
|
+
aspect: "all"
|
|
2775
|
+
});
|
|
2776
|
+
__publicField(Texture, "defaultTextureWriteOptions", {
|
|
2777
|
+
byteOffset: 0,
|
|
2778
|
+
bytesPerRow: void 0,
|
|
2779
|
+
rowsPerImage: void 0,
|
|
2780
|
+
x: 0,
|
|
2781
|
+
y: 0,
|
|
2782
|
+
z: 0,
|
|
2783
|
+
width: void 0,
|
|
2784
|
+
height: void 0,
|
|
2785
|
+
depthOrArrayLayers: 1,
|
|
2786
|
+
mipLevel: 0,
|
|
2787
|
+
aspect: "all"
|
|
2788
|
+
});
|
|
1873
2789
|
|
|
1874
2790
|
// dist/adapter/resources/texture-view.js
|
|
1875
2791
|
var _TextureView = class extends Resource {
|
|
@@ -1916,24 +2832,32 @@ function formatCompilerLog(shaderLog, source, options) {
|
|
|
1916
2832
|
const log2 = shaderLog.slice().sort((a, b) => a.lineNum - b.lineNum);
|
|
1917
2833
|
switch ((options == null ? void 0 : options.showSourceCode) || "no") {
|
|
1918
2834
|
case "all":
|
|
1919
|
-
let
|
|
2835
|
+
let currentMessageIndex = 0;
|
|
1920
2836
|
for (let lineNum = 1; lineNum <= lines.length; lineNum++) {
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
formattedLog +=
|
|
2837
|
+
const line = lines[lineNum - 1];
|
|
2838
|
+
const currentMessage = log2[currentMessageIndex];
|
|
2839
|
+
if (line && currentMessage) {
|
|
2840
|
+
formattedLog += getNumberedLine(line, lineNum, options);
|
|
2841
|
+
}
|
|
2842
|
+
while (log2.length > currentMessageIndex && currentMessage.lineNum === lineNum) {
|
|
2843
|
+
const message = log2[currentMessageIndex++];
|
|
2844
|
+
if (message) {
|
|
2845
|
+
formattedLog += formatCompilerMessage(message, lines, message.lineNum, {
|
|
2846
|
+
...options,
|
|
2847
|
+
inlineSource: false
|
|
2848
|
+
});
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2852
|
+
while (log2.length > currentMessageIndex) {
|
|
2853
|
+
const message = log2[currentMessageIndex++];
|
|
2854
|
+
if (message) {
|
|
2855
|
+
formattedLog += formatCompilerMessage(message, [], 0, {
|
|
1925
2856
|
...options,
|
|
1926
2857
|
inlineSource: false
|
|
1927
2858
|
});
|
|
1928
2859
|
}
|
|
1929
2860
|
}
|
|
1930
|
-
while (log2.length > currentMessage) {
|
|
1931
|
-
const message = log2[currentMessage++];
|
|
1932
|
-
formattedLog += formatCompilerMessage(message, [], 0, {
|
|
1933
|
-
...options,
|
|
1934
|
-
inlineSource: false
|
|
1935
|
-
});
|
|
1936
|
-
}
|
|
1937
2861
|
return formattedLog;
|
|
1938
2862
|
case "issues":
|
|
1939
2863
|
case "no":
|
|
@@ -1955,8 +2879,8 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
|
|
|
1955
2879
|
|
|
1956
2880
|
`;
|
|
1957
2881
|
}
|
|
1958
|
-
const color = message.type === "error" ? "red" : "
|
|
1959
|
-
return (options == null ? void 0 : options.html) ? `<div class='luma-compiler-log
|
|
2882
|
+
const color = message.type === "error" ? "red" : "orange";
|
|
2883
|
+
return (options == null ? void 0 : options.html) ? `<div class='luma-compiler-log-${message.type}' style="color:${color};"><b> ${message.type.toUpperCase()}: ${message.message}</b></div>` : `${message.type.toUpperCase()}: ${message.message}`;
|
|
1960
2884
|
}
|
|
1961
2885
|
function getNumberedLines(lines, lineNum, options) {
|
|
1962
2886
|
let numberedLines = "";
|
|
@@ -2037,35 +2961,39 @@ var _Shader = class extends Resource {
|
|
|
2037
2961
|
* TODO - this HTML formatting code should not be in Device, should be pluggable
|
|
2038
2962
|
*/
|
|
2039
2963
|
_displayShaderLog(messages, shaderId) {
|
|
2040
|
-
var _a;
|
|
2041
2964
|
if (typeof document === "undefined" || !(document == null ? void 0 : document.createElement)) {
|
|
2042
2965
|
return;
|
|
2043
2966
|
}
|
|
2044
2967
|
const shaderName = shaderId;
|
|
2045
2968
|
const shaderTitle = `${this.stage} shader "${shaderName}"`;
|
|
2046
|
-
|
|
2969
|
+
const htmlLog = formatCompilerLog(messages, this.source, { showSourceCode: "all", html: true });
|
|
2047
2970
|
const translatedSource = this.getTranslatedSource();
|
|
2971
|
+
const container = document.createElement("div");
|
|
2972
|
+
container.innerHTML = `<h1>Compilation error in ${shaderTitle}</h1>
|
|
2973
|
+
<div style="display:flex;position:fixed;top:10px;right:20px;gap:2px;">
|
|
2974
|
+
<button id="copy">Copy source</button><br/>
|
|
2975
|
+
<button id="close">Close</button>
|
|
2976
|
+
</div>
|
|
2977
|
+
<code><pre>${htmlLog}</pre></code>`;
|
|
2048
2978
|
if (translatedSource) {
|
|
2049
|
-
|
|
2050
|
-
}
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
button.
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
(
|
|
2066
|
-
|
|
2067
|
-
const dataURI = `data:text/plain,${encodeURIComponent(this.source)}`;
|
|
2068
|
-
navigator.clipboard.writeText(dataURI);
|
|
2979
|
+
container.innerHTML += `<br /><h1>Translated Source</h1><br /><br /><code><pre>${translatedSource}</pre></code>`;
|
|
2980
|
+
}
|
|
2981
|
+
container.style.top = "0";
|
|
2982
|
+
container.style.left = "0";
|
|
2983
|
+
container.style.background = "white";
|
|
2984
|
+
container.style.position = "fixed";
|
|
2985
|
+
container.style.zIndex = "9999";
|
|
2986
|
+
container.style.maxWidth = "100vw";
|
|
2987
|
+
container.style.maxHeight = "100vh";
|
|
2988
|
+
container.style.overflowY = "auto";
|
|
2989
|
+
document.body.appendChild(container);
|
|
2990
|
+
const error = container.querySelector(".luma-compiler-log-error");
|
|
2991
|
+
error == null ? void 0 : error.scrollIntoView();
|
|
2992
|
+
container.querySelector("button#close").onclick = () => {
|
|
2993
|
+
container.remove();
|
|
2994
|
+
};
|
|
2995
|
+
container.querySelector("button#copy").onclick = () => {
|
|
2996
|
+
navigator.clipboard.writeText(this.source);
|
|
2069
2997
|
};
|
|
2070
2998
|
}
|
|
2071
2999
|
};
|
|
@@ -2085,7 +3013,7 @@ function getShaderIdFromProps(props) {
|
|
|
2085
3013
|
function getShaderName(shader, defaultName = "unnamed") {
|
|
2086
3014
|
const SHADER_NAME_REGEXP = /#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/;
|
|
2087
3015
|
const match = SHADER_NAME_REGEXP.exec(shader);
|
|
2088
|
-
return match ? match[1]
|
|
3016
|
+
return (match == null ? void 0 : match[1]) ?? defaultName;
|
|
2089
3017
|
}
|
|
2090
3018
|
|
|
2091
3019
|
// dist/adapter/resources/framebuffer.js
|
|
@@ -2109,7 +3037,12 @@ var _Framebuffer = class extends Resource {
|
|
|
2109
3037
|
clone(size) {
|
|
2110
3038
|
const colorAttachments = this.colorAttachments.map((colorAttachment) => colorAttachment.texture.clone(size));
|
|
2111
3039
|
const depthStencilAttachment = this.depthStencilAttachment && this.depthStencilAttachment.texture.clone(size);
|
|
2112
|
-
return this.device.createFramebuffer({
|
|
3040
|
+
return this.device.createFramebuffer({
|
|
3041
|
+
...this.props,
|
|
3042
|
+
...size,
|
|
3043
|
+
colorAttachments,
|
|
3044
|
+
depthStencilAttachment
|
|
3045
|
+
});
|
|
2113
3046
|
}
|
|
2114
3047
|
resize(size) {
|
|
2115
3048
|
let updateSize = !size;
|
|
@@ -2184,17 +3117,15 @@ var _Framebuffer = class extends Resource {
|
|
|
2184
3117
|
* and destroys existing textures if owned
|
|
2185
3118
|
*/
|
|
2186
3119
|
resizeAttachments(width, height) {
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
}
|
|
2197
|
-
}
|
|
3120
|
+
this.colorAttachments.forEach((colorAttachment, i) => {
|
|
3121
|
+
const resizedTexture = colorAttachment.texture.clone({
|
|
3122
|
+
width,
|
|
3123
|
+
height
|
|
3124
|
+
});
|
|
3125
|
+
this.destroyAttachedResource(colorAttachment);
|
|
3126
|
+
this.colorAttachments[i] = resizedTexture.view;
|
|
3127
|
+
this.attachResource(resizedTexture.view);
|
|
3128
|
+
});
|
|
2198
3129
|
if (this.depthStencilAttachment) {
|
|
2199
3130
|
const resizedTexture = this.depthStencilAttachment.texture.clone({
|
|
2200
3131
|
width,
|
|
@@ -2231,10 +3162,23 @@ var _RenderPipeline = class extends Resource {
|
|
|
2231
3162
|
linkStatus = "pending";
|
|
2232
3163
|
/** The hash of the pipeline */
|
|
2233
3164
|
hash = "";
|
|
3165
|
+
/** Optional shared backend implementation */
|
|
3166
|
+
sharedRenderPipeline = null;
|
|
3167
|
+
/** Whether shader or pipeline compilation/linking is still in progress */
|
|
3168
|
+
get isPending() {
|
|
3169
|
+
var _a;
|
|
3170
|
+
return this.linkStatus === "pending" || this.vs.compilationStatus === "pending" || ((_a = this.fs) == null ? void 0 : _a.compilationStatus) === "pending";
|
|
3171
|
+
}
|
|
3172
|
+
/** Whether shader or pipeline compilation/linking has failed */
|
|
3173
|
+
get isErrored() {
|
|
3174
|
+
var _a;
|
|
3175
|
+
return this.linkStatus === "error" || this.vs.compilationStatus === "error" || ((_a = this.fs) == null ? void 0 : _a.compilationStatus) === "error";
|
|
3176
|
+
}
|
|
2234
3177
|
constructor(device, props) {
|
|
2235
3178
|
super(device, props, _RenderPipeline.defaultProps);
|
|
2236
3179
|
this.shaderLayout = this.props.shaderLayout;
|
|
2237
3180
|
this.bufferLayout = this.props.bufferLayout || [];
|
|
3181
|
+
this.sharedRenderPipeline = this.props._sharedRenderPipeline || null;
|
|
2238
3182
|
}
|
|
2239
3183
|
};
|
|
2240
3184
|
var RenderPipeline = _RenderPipeline;
|
|
@@ -2252,47 +3196,30 @@ __publicField(RenderPipeline, "defaultProps", {
|
|
|
2252
3196
|
colorAttachmentFormats: void 0,
|
|
2253
3197
|
depthStencilAttachmentFormat: void 0,
|
|
2254
3198
|
parameters: {},
|
|
2255
|
-
|
|
2256
|
-
|
|
3199
|
+
varyings: void 0,
|
|
3200
|
+
bufferMode: void 0,
|
|
3201
|
+
disableWarnings: false,
|
|
3202
|
+
_sharedRenderPipeline: void 0,
|
|
3203
|
+
bindings: void 0,
|
|
3204
|
+
bindGroups: void 0
|
|
2257
3205
|
});
|
|
2258
3206
|
|
|
2259
|
-
// dist/adapter/resources/render-
|
|
2260
|
-
var
|
|
3207
|
+
// dist/adapter/resources/shared-render-pipeline.js
|
|
3208
|
+
var SharedRenderPipeline = class extends Resource {
|
|
2261
3209
|
get [Symbol.toStringTag]() {
|
|
2262
|
-
return "
|
|
3210
|
+
return "SharedRenderPipeline";
|
|
2263
3211
|
}
|
|
2264
3212
|
constructor(device, props) {
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
3213
|
+
super(device, props, {
|
|
3214
|
+
...Resource.defaultProps,
|
|
3215
|
+
handle: void 0,
|
|
3216
|
+
vs: void 0,
|
|
3217
|
+
fs: void 0,
|
|
3218
|
+
varyings: void 0,
|
|
3219
|
+
bufferMode: void 0
|
|
3220
|
+
});
|
|
2270
3221
|
}
|
|
2271
3222
|
};
|
|
2272
|
-
var RenderPass = _RenderPass;
|
|
2273
|
-
/** TODO - should be [0, 0, 0, 0], update once deck.gl tests run clean */
|
|
2274
|
-
__publicField(RenderPass, "defaultClearColor", [0, 0, 0, 1]);
|
|
2275
|
-
/** Depth 1.0 represents the far plance */
|
|
2276
|
-
__publicField(RenderPass, "defaultClearDepth", 1);
|
|
2277
|
-
/** Clears all stencil bits */
|
|
2278
|
-
__publicField(RenderPass, "defaultClearStencil", 0);
|
|
2279
|
-
/** Default properties for RenderPass */
|
|
2280
|
-
__publicField(RenderPass, "defaultProps", {
|
|
2281
|
-
...Resource.defaultProps,
|
|
2282
|
-
framebuffer: null,
|
|
2283
|
-
parameters: void 0,
|
|
2284
|
-
clearColor: _RenderPass.defaultClearColor,
|
|
2285
|
-
clearColors: void 0,
|
|
2286
|
-
clearDepth: _RenderPass.defaultClearDepth,
|
|
2287
|
-
clearStencil: _RenderPass.defaultClearStencil,
|
|
2288
|
-
depthReadOnly: false,
|
|
2289
|
-
stencilReadOnly: false,
|
|
2290
|
-
discard: false,
|
|
2291
|
-
occlusionQuerySet: void 0,
|
|
2292
|
-
timestampQuerySet: void 0,
|
|
2293
|
-
beginTimestampIndex: void 0,
|
|
2294
|
-
endTimestampIndex: void 0
|
|
2295
|
-
});
|
|
2296
3223
|
|
|
2297
3224
|
// dist/adapter/resources/compute-pipeline.js
|
|
2298
3225
|
var _ComputePipeline = class extends Resource {
|
|
@@ -2316,62 +3243,594 @@ __publicField(ComputePipeline, "defaultProps", {
|
|
|
2316
3243
|
shaderLayout: void 0
|
|
2317
3244
|
});
|
|
2318
3245
|
|
|
2319
|
-
// dist/
|
|
2320
|
-
var
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
return
|
|
2326
|
-
}
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
endTimestampIndex: void 0
|
|
2334
|
-
});
|
|
2335
|
-
|
|
2336
|
-
// dist/adapter/resources/command-encoder.js
|
|
2337
|
-
var _CommandEncoder = class extends Resource {
|
|
3246
|
+
// dist/factories/pipeline-factory.js
|
|
3247
|
+
var _PipelineFactory = class {
|
|
3248
|
+
/** Get the singleton default pipeline factory for the specified device */
|
|
3249
|
+
static getDefaultPipelineFactory(device) {
|
|
3250
|
+
const moduleData = device.getModuleData("@luma.gl/core");
|
|
3251
|
+
moduleData.defaultPipelineFactory ||= new _PipelineFactory(device);
|
|
3252
|
+
return moduleData.defaultPipelineFactory;
|
|
3253
|
+
}
|
|
3254
|
+
device;
|
|
3255
|
+
_hashCounter = 0;
|
|
3256
|
+
_hashes = {};
|
|
3257
|
+
_renderPipelineCache = {};
|
|
3258
|
+
_computePipelineCache = {};
|
|
3259
|
+
_sharedRenderPipelineCache = {};
|
|
2338
3260
|
get [Symbol.toStringTag]() {
|
|
2339
|
-
return "
|
|
3261
|
+
return "PipelineFactory";
|
|
2340
3262
|
}
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
}
|
|
2344
|
-
};
|
|
2345
|
-
var CommandEncoder = _CommandEncoder;
|
|
2346
|
-
// TODO - luma.gl has these on the device, should we align with WebGPU API?
|
|
2347
|
-
// beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
|
|
2348
|
-
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
2349
|
-
__publicField(CommandEncoder, "defaultProps", {
|
|
2350
|
-
...Resource.defaultProps,
|
|
2351
|
-
measureExecutionTime: void 0
|
|
2352
|
-
});
|
|
2353
|
-
|
|
2354
|
-
// dist/adapter/resources/command-buffer.js
|
|
2355
|
-
var _CommandBuffer = class extends Resource {
|
|
2356
|
-
get [Symbol.toStringTag]() {
|
|
2357
|
-
return "CommandBuffer";
|
|
3263
|
+
toString() {
|
|
3264
|
+
return `PipelineFactory(${this.device.id})`;
|
|
2358
3265
|
}
|
|
2359
|
-
constructor(device
|
|
2360
|
-
|
|
3266
|
+
constructor(device) {
|
|
3267
|
+
this.device = device;
|
|
2361
3268
|
}
|
|
2362
|
-
|
|
3269
|
+
/**
|
|
3270
|
+
* WebGL has two cache layers with different priorities:
|
|
3271
|
+
* - `_sharedRenderPipelineCache` owns `WEBGLSharedRenderPipeline` / `WebGLProgram` reuse.
|
|
3272
|
+
* - `_renderPipelineCache` owns `RenderPipeline` wrapper reuse.
|
|
3273
|
+
*
|
|
3274
|
+
* Shared WebGL program reuse is the hard requirement. Wrapper reuse is beneficial,
|
|
3275
|
+
* but wrapper cache misses are acceptable if that keeps the cache logic simple and
|
|
3276
|
+
* prevents incorrect cache hits.
|
|
3277
|
+
*
|
|
3278
|
+
* In particular, wrapper hash logic must never force program creation or linked-program
|
|
3279
|
+
* introspection just to decide whether a shared WebGL program can be reused.
|
|
3280
|
+
*/
|
|
3281
|
+
/** Return a RenderPipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
3282
|
+
createRenderPipeline(props) {
|
|
3283
|
+
var _a;
|
|
3284
|
+
if (!this.device.props._cachePipelines) {
|
|
3285
|
+
return this.device.createRenderPipeline(props);
|
|
3286
|
+
}
|
|
3287
|
+
const allProps = { ...RenderPipeline.defaultProps, ...props };
|
|
3288
|
+
const cache = this._renderPipelineCache;
|
|
3289
|
+
const hash = this._hashRenderPipeline(allProps);
|
|
3290
|
+
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.resource;
|
|
3291
|
+
if (!pipeline) {
|
|
3292
|
+
const sharedRenderPipeline = this.device.type === "webgl" && this.device.props._sharePipelines ? this.createSharedRenderPipeline(allProps) : void 0;
|
|
3293
|
+
pipeline = this.device.createRenderPipeline({
|
|
3294
|
+
...allProps,
|
|
3295
|
+
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached"),
|
|
3296
|
+
_sharedRenderPipeline: sharedRenderPipeline
|
|
3297
|
+
});
|
|
3298
|
+
pipeline.hash = hash;
|
|
3299
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
3300
|
+
if (this.device.props.debugFactories) {
|
|
3301
|
+
log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
3302
|
+
}
|
|
3303
|
+
} else {
|
|
3304
|
+
cache[hash].useCount++;
|
|
3305
|
+
if (this.device.props.debugFactories) {
|
|
3306
|
+
log.log(3, `${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
|
|
3307
|
+
}
|
|
3308
|
+
}
|
|
3309
|
+
return pipeline;
|
|
3310
|
+
}
|
|
3311
|
+
/** Return a ComputePipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
3312
|
+
createComputePipeline(props) {
|
|
3313
|
+
var _a;
|
|
3314
|
+
if (!this.device.props._cachePipelines) {
|
|
3315
|
+
return this.device.createComputePipeline(props);
|
|
3316
|
+
}
|
|
3317
|
+
const allProps = { ...ComputePipeline.defaultProps, ...props };
|
|
3318
|
+
const cache = this._computePipelineCache;
|
|
3319
|
+
const hash = this._hashComputePipeline(allProps);
|
|
3320
|
+
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.resource;
|
|
3321
|
+
if (!pipeline) {
|
|
3322
|
+
pipeline = this.device.createComputePipeline({
|
|
3323
|
+
...allProps,
|
|
3324
|
+
id: allProps.id ? `${allProps.id}-cached` : void 0
|
|
3325
|
+
});
|
|
3326
|
+
pipeline.hash = hash;
|
|
3327
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
3328
|
+
if (this.device.props.debugFactories) {
|
|
3329
|
+
log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
3330
|
+
}
|
|
3331
|
+
} else {
|
|
3332
|
+
cache[hash].useCount++;
|
|
3333
|
+
if (this.device.props.debugFactories) {
|
|
3334
|
+
log.log(3, `${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
|
|
3335
|
+
}
|
|
3336
|
+
}
|
|
3337
|
+
return pipeline;
|
|
3338
|
+
}
|
|
3339
|
+
release(pipeline) {
|
|
3340
|
+
if (!this.device.props._cachePipelines) {
|
|
3341
|
+
pipeline.destroy();
|
|
3342
|
+
return;
|
|
3343
|
+
}
|
|
3344
|
+
const cache = this._getCache(pipeline);
|
|
3345
|
+
const hash = pipeline.hash;
|
|
3346
|
+
cache[hash].useCount--;
|
|
3347
|
+
if (cache[hash].useCount === 0) {
|
|
3348
|
+
this._destroyPipeline(pipeline);
|
|
3349
|
+
if (this.device.props.debugFactories) {
|
|
3350
|
+
log.log(3, `${this}: ${pipeline} released and destroyed`)();
|
|
3351
|
+
}
|
|
3352
|
+
} else if (cache[hash].useCount < 0) {
|
|
3353
|
+
log.error(`${this}: ${pipeline} released, useCount < 0, resetting`)();
|
|
3354
|
+
cache[hash].useCount = 0;
|
|
3355
|
+
} else if (this.device.props.debugFactories) {
|
|
3356
|
+
log.log(3, `${this}: ${pipeline} released, count=${cache[hash].useCount}`)();
|
|
3357
|
+
}
|
|
3358
|
+
}
|
|
3359
|
+
createSharedRenderPipeline(props) {
|
|
3360
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(props);
|
|
3361
|
+
let sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
3362
|
+
if (!sharedCacheItem) {
|
|
3363
|
+
const sharedRenderPipeline = this.device._createSharedRenderPipelineWebGL(props);
|
|
3364
|
+
sharedCacheItem = { resource: sharedRenderPipeline, useCount: 0 };
|
|
3365
|
+
this._sharedRenderPipelineCache[sharedPipelineHash] = sharedCacheItem;
|
|
3366
|
+
}
|
|
3367
|
+
sharedCacheItem.useCount++;
|
|
3368
|
+
return sharedCacheItem.resource;
|
|
3369
|
+
}
|
|
3370
|
+
releaseSharedRenderPipeline(pipeline) {
|
|
3371
|
+
if (!pipeline.sharedRenderPipeline) {
|
|
3372
|
+
return;
|
|
3373
|
+
}
|
|
3374
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(pipeline.sharedRenderPipeline.props);
|
|
3375
|
+
const sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
3376
|
+
if (!sharedCacheItem) {
|
|
3377
|
+
return;
|
|
3378
|
+
}
|
|
3379
|
+
sharedCacheItem.useCount--;
|
|
3380
|
+
if (sharedCacheItem.useCount === 0) {
|
|
3381
|
+
sharedCacheItem.resource.destroy();
|
|
3382
|
+
delete this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
// PRIVATE
|
|
3386
|
+
/** Destroy a cached pipeline, removing it from the cache if configured to do so. */
|
|
3387
|
+
_destroyPipeline(pipeline) {
|
|
3388
|
+
const cache = this._getCache(pipeline);
|
|
3389
|
+
if (!this.device.props._destroyPipelines) {
|
|
3390
|
+
return false;
|
|
3391
|
+
}
|
|
3392
|
+
delete cache[pipeline.hash];
|
|
3393
|
+
pipeline.destroy();
|
|
3394
|
+
if (pipeline instanceof RenderPipeline) {
|
|
3395
|
+
this.releaseSharedRenderPipeline(pipeline);
|
|
3396
|
+
}
|
|
3397
|
+
return true;
|
|
3398
|
+
}
|
|
3399
|
+
/** Get the appropriate cache for the type of pipeline */
|
|
3400
|
+
_getCache(pipeline) {
|
|
3401
|
+
let cache;
|
|
3402
|
+
if (pipeline instanceof ComputePipeline) {
|
|
3403
|
+
cache = this._computePipelineCache;
|
|
3404
|
+
}
|
|
3405
|
+
if (pipeline instanceof RenderPipeline) {
|
|
3406
|
+
cache = this._renderPipelineCache;
|
|
3407
|
+
}
|
|
3408
|
+
if (!cache) {
|
|
3409
|
+
throw new Error(`${this}`);
|
|
3410
|
+
}
|
|
3411
|
+
if (!cache[pipeline.hash]) {
|
|
3412
|
+
throw new Error(`${this}: ${pipeline} matched incorrect entry`);
|
|
3413
|
+
}
|
|
3414
|
+
return cache;
|
|
3415
|
+
}
|
|
3416
|
+
/** Calculate a hash based on all the inputs for a compute pipeline */
|
|
3417
|
+
_hashComputePipeline(props) {
|
|
3418
|
+
const { type } = this.device;
|
|
3419
|
+
const shaderHash = this._getHash(props.shader.source);
|
|
3420
|
+
const shaderLayoutHash = this._getHash(JSON.stringify(props.shaderLayout));
|
|
3421
|
+
return `${type}/C/${shaderHash}SL${shaderLayoutHash}`;
|
|
3422
|
+
}
|
|
3423
|
+
/** Calculate a hash based on all the inputs for a render pipeline */
|
|
3424
|
+
_hashRenderPipeline(props) {
|
|
3425
|
+
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
3426
|
+
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
3427
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
3428
|
+
const shaderLayoutHash = this._getHash(JSON.stringify(props.shaderLayout));
|
|
3429
|
+
const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
|
|
3430
|
+
const { type } = this.device;
|
|
3431
|
+
switch (type) {
|
|
3432
|
+
case "webgl":
|
|
3433
|
+
const webglParameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
3434
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${webglParameterHash}SL${shaderLayoutHash}BL${bufferLayoutHash}`;
|
|
3435
|
+
case "webgpu":
|
|
3436
|
+
default:
|
|
3437
|
+
const entryPointHash = this._getHash(JSON.stringify({
|
|
3438
|
+
vertexEntryPoint: props.vertexEntryPoint,
|
|
3439
|
+
fragmentEntryPoint: props.fragmentEntryPoint
|
|
3440
|
+
}));
|
|
3441
|
+
const parameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
3442
|
+
const attachmentHash = this._getWebGPUAttachmentHash(props);
|
|
3443
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}EP${entryPointHash}P${parameterHash}SL${shaderLayoutHash}BL${bufferLayoutHash}A${attachmentHash}`;
|
|
3444
|
+
}
|
|
3445
|
+
}
|
|
3446
|
+
// This is the only gate for shared `WebGLProgram` reuse.
|
|
3447
|
+
// Only include inputs that affect program linking or transform-feedback linkage.
|
|
3448
|
+
// Wrapper-only concerns such as topology, parameters, attachment formats and layout
|
|
3449
|
+
// overrides must not be added here.
|
|
3450
|
+
_hashSharedRenderPipeline(props) {
|
|
3451
|
+
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
3452
|
+
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
3453
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
3454
|
+
return `webgl/S/${vsHash}/${fsHash}V${varyingHash}`;
|
|
3455
|
+
}
|
|
3456
|
+
_getHash(key) {
|
|
3457
|
+
if (this._hashes[key] === void 0) {
|
|
3458
|
+
this._hashes[key] = this._hashCounter++;
|
|
3459
|
+
}
|
|
3460
|
+
return this._hashes[key];
|
|
3461
|
+
}
|
|
3462
|
+
_getWebGLVaryingHash(props) {
|
|
3463
|
+
const { varyings = [], bufferMode = null } = props;
|
|
3464
|
+
return this._getHash(JSON.stringify({ varyings, bufferMode }));
|
|
3465
|
+
}
|
|
3466
|
+
_getWebGPUAttachmentHash(props) {
|
|
3467
|
+
var _a;
|
|
3468
|
+
const colorAttachmentFormats = props.colorAttachmentFormats ?? [
|
|
3469
|
+
this.device.preferredColorFormat
|
|
3470
|
+
];
|
|
3471
|
+
const depthStencilAttachmentFormat = ((_a = props.parameters) == null ? void 0 : _a.depthWriteEnabled) ? props.depthStencilAttachmentFormat || this.device.preferredDepthFormat : null;
|
|
3472
|
+
return this._getHash(JSON.stringify({
|
|
3473
|
+
colorAttachmentFormats,
|
|
3474
|
+
depthStencilAttachmentFormat
|
|
3475
|
+
}));
|
|
3476
|
+
}
|
|
3477
|
+
};
|
|
3478
|
+
var PipelineFactory = _PipelineFactory;
|
|
3479
|
+
__publicField(PipelineFactory, "defaultProps", { ...RenderPipeline.defaultProps });
|
|
3480
|
+
|
|
3481
|
+
// dist/factories/shader-factory.js
|
|
3482
|
+
var _ShaderFactory = class {
|
|
3483
|
+
/** Returns the default ShaderFactory for the given {@link Device}, creating one if necessary. */
|
|
3484
|
+
static getDefaultShaderFactory(device) {
|
|
3485
|
+
const moduleData = device.getModuleData("@luma.gl/core");
|
|
3486
|
+
moduleData.defaultShaderFactory ||= new _ShaderFactory(device);
|
|
3487
|
+
return moduleData.defaultShaderFactory;
|
|
3488
|
+
}
|
|
3489
|
+
device;
|
|
3490
|
+
_cache = {};
|
|
3491
|
+
get [Symbol.toStringTag]() {
|
|
3492
|
+
return "ShaderFactory";
|
|
3493
|
+
}
|
|
3494
|
+
toString() {
|
|
3495
|
+
return `${this[Symbol.toStringTag]}(${this.device.id})`;
|
|
3496
|
+
}
|
|
3497
|
+
/** @internal */
|
|
3498
|
+
constructor(device) {
|
|
3499
|
+
this.device = device;
|
|
3500
|
+
}
|
|
3501
|
+
/** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
|
|
3502
|
+
createShader(props) {
|
|
3503
|
+
if (!this.device.props._cacheShaders) {
|
|
3504
|
+
return this.device.createShader(props);
|
|
3505
|
+
}
|
|
3506
|
+
const key = this._hashShader(props);
|
|
3507
|
+
let cacheEntry = this._cache[key];
|
|
3508
|
+
if (!cacheEntry) {
|
|
3509
|
+
const resource = this.device.createShader({
|
|
3510
|
+
...props,
|
|
3511
|
+
id: props.id ? `${props.id}-cached` : void 0
|
|
3512
|
+
});
|
|
3513
|
+
this._cache[key] = cacheEntry = { resource, useCount: 1 };
|
|
3514
|
+
if (this.device.props.debugFactories) {
|
|
3515
|
+
log.log(3, `${this}: Created new shader ${resource.id}`)();
|
|
3516
|
+
}
|
|
3517
|
+
} else {
|
|
3518
|
+
cacheEntry.useCount++;
|
|
3519
|
+
if (this.device.props.debugFactories) {
|
|
3520
|
+
log.log(3, `${this}: Reusing shader ${cacheEntry.resource.id} count=${cacheEntry.useCount}`)();
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
3523
|
+
return cacheEntry.resource;
|
|
3524
|
+
}
|
|
3525
|
+
/** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
|
|
3526
|
+
release(shader) {
|
|
3527
|
+
if (!this.device.props._cacheShaders) {
|
|
3528
|
+
shader.destroy();
|
|
3529
|
+
return;
|
|
3530
|
+
}
|
|
3531
|
+
const key = this._hashShader(shader);
|
|
3532
|
+
const cacheEntry = this._cache[key];
|
|
3533
|
+
if (cacheEntry) {
|
|
3534
|
+
cacheEntry.useCount--;
|
|
3535
|
+
if (cacheEntry.useCount === 0) {
|
|
3536
|
+
if (this.device.props._destroyShaders) {
|
|
3537
|
+
delete this._cache[key];
|
|
3538
|
+
cacheEntry.resource.destroy();
|
|
3539
|
+
if (this.device.props.debugFactories) {
|
|
3540
|
+
log.log(3, `${this}: Releasing shader ${shader.id}, destroyed`)();
|
|
3541
|
+
}
|
|
3542
|
+
}
|
|
3543
|
+
} else if (cacheEntry.useCount < 0) {
|
|
3544
|
+
throw new Error(`ShaderFactory: Shader ${shader.id} released too many times`);
|
|
3545
|
+
} else if (this.device.props.debugFactories) {
|
|
3546
|
+
log.log(3, `${this}: Releasing shader ${shader.id} count=${cacheEntry.useCount}`)();
|
|
3547
|
+
}
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
// PRIVATE
|
|
3551
|
+
_hashShader(value) {
|
|
3552
|
+
return `${value.stage}:${value.source}`;
|
|
3553
|
+
}
|
|
3554
|
+
};
|
|
3555
|
+
var ShaderFactory = _ShaderFactory;
|
|
3556
|
+
__publicField(ShaderFactory, "defaultProps", { ...Shader.defaultProps });
|
|
3557
|
+
|
|
3558
|
+
// dist/adapter-utils/bind-groups.js
|
|
3559
|
+
function getShaderLayoutBinding(shaderLayout, bindingName, options) {
|
|
3560
|
+
const bindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName || `${binding.name.toLocaleLowerCase()}uniforms` === bindingName.toLocaleLowerCase());
|
|
3561
|
+
if (!bindingLayout && !(options == null ? void 0 : options.ignoreWarnings)) {
|
|
3562
|
+
log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
|
|
3563
|
+
}
|
|
3564
|
+
return bindingLayout || null;
|
|
3565
|
+
}
|
|
3566
|
+
function normalizeBindingsByGroup(shaderLayout, bindingsOrBindGroups) {
|
|
3567
|
+
if (!bindingsOrBindGroups) {
|
|
3568
|
+
return {};
|
|
3569
|
+
}
|
|
3570
|
+
if (areBindingsGrouped(bindingsOrBindGroups)) {
|
|
3571
|
+
const bindGroups2 = bindingsOrBindGroups;
|
|
3572
|
+
return Object.fromEntries(Object.entries(bindGroups2).map(([group, bindings]) => [Number(group), { ...bindings }]));
|
|
3573
|
+
}
|
|
3574
|
+
const bindGroups = {};
|
|
3575
|
+
for (const [bindingName, binding] of Object.entries(bindingsOrBindGroups)) {
|
|
3576
|
+
const bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);
|
|
3577
|
+
const group = (bindingLayout == null ? void 0 : bindingLayout.group) ?? 0;
|
|
3578
|
+
bindGroups[group] ||= {};
|
|
3579
|
+
bindGroups[group][bindingName] = binding;
|
|
3580
|
+
}
|
|
3581
|
+
return bindGroups;
|
|
3582
|
+
}
|
|
3583
|
+
function flattenBindingsByGroup(bindGroups) {
|
|
3584
|
+
const bindings = {};
|
|
3585
|
+
for (const groupBindings of Object.values(bindGroups)) {
|
|
3586
|
+
Object.assign(bindings, groupBindings);
|
|
3587
|
+
}
|
|
3588
|
+
return bindings;
|
|
3589
|
+
}
|
|
3590
|
+
function areBindingsGrouped(bindingsOrBindGroups) {
|
|
3591
|
+
const keys = Object.keys(bindingsOrBindGroups);
|
|
3592
|
+
return keys.length > 0 && keys.every((key) => /^\d+$/.test(key));
|
|
3593
|
+
}
|
|
3594
|
+
|
|
3595
|
+
// dist/factories/bind-group-factory.js
|
|
3596
|
+
var BindGroupFactory = class {
|
|
3597
|
+
device;
|
|
3598
|
+
_layoutCacheByPipeline = /* @__PURE__ */ new WeakMap();
|
|
3599
|
+
_bindGroupCacheByLayout = /* @__PURE__ */ new WeakMap();
|
|
3600
|
+
constructor(device) {
|
|
3601
|
+
this.device = device;
|
|
3602
|
+
}
|
|
3603
|
+
getBindGroups(pipeline, bindings, bindGroupCacheKeys) {
|
|
3604
|
+
if (this.device.type !== "webgpu" || pipeline.shaderLayout.bindings.length === 0) {
|
|
3605
|
+
return {};
|
|
3606
|
+
}
|
|
3607
|
+
const bindingsByGroup = normalizeBindingsByGroup(pipeline.shaderLayout, bindings);
|
|
3608
|
+
const resolvedBindGroups = {};
|
|
3609
|
+
for (const group of getBindGroupIndicesUpToMax(pipeline.shaderLayout.bindings)) {
|
|
3610
|
+
const groupBindings = bindingsByGroup[group];
|
|
3611
|
+
const bindGroupLayout = this._getBindGroupLayout(pipeline, group);
|
|
3612
|
+
if (!groupBindings || Object.keys(groupBindings).length === 0) {
|
|
3613
|
+
if (!hasBindingsInGroup(pipeline.shaderLayout.bindings, group)) {
|
|
3614
|
+
resolvedBindGroups[group] = this._getEmptyBindGroup(bindGroupLayout, pipeline.shaderLayout, group);
|
|
3615
|
+
}
|
|
3616
|
+
continue;
|
|
3617
|
+
}
|
|
3618
|
+
const bindGroupCacheKey = bindGroupCacheKeys == null ? void 0 : bindGroupCacheKeys[group];
|
|
3619
|
+
if (bindGroupCacheKey) {
|
|
3620
|
+
const layoutCache = this._getLayoutBindGroupCache(bindGroupLayout);
|
|
3621
|
+
if (layoutCache.bindGroupsBySource.has(bindGroupCacheKey)) {
|
|
3622
|
+
resolvedBindGroups[group] = layoutCache.bindGroupsBySource.get(bindGroupCacheKey) || null;
|
|
3623
|
+
continue;
|
|
3624
|
+
}
|
|
3625
|
+
const bindGroup = this.device._createBindGroupWebGPU(bindGroupLayout, pipeline.shaderLayout, groupBindings, group);
|
|
3626
|
+
layoutCache.bindGroupsBySource.set(bindGroupCacheKey, bindGroup);
|
|
3627
|
+
resolvedBindGroups[group] = bindGroup;
|
|
3628
|
+
} else {
|
|
3629
|
+
resolvedBindGroups[group] = this.device._createBindGroupWebGPU(bindGroupLayout, pipeline.shaderLayout, groupBindings, group);
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
return resolvedBindGroups;
|
|
3633
|
+
}
|
|
3634
|
+
_getBindGroupLayout(pipeline, group) {
|
|
3635
|
+
let layoutCache = this._layoutCacheByPipeline.get(pipeline);
|
|
3636
|
+
if (!layoutCache) {
|
|
3637
|
+
layoutCache = {};
|
|
3638
|
+
this._layoutCacheByPipeline.set(pipeline, layoutCache);
|
|
3639
|
+
}
|
|
3640
|
+
layoutCache[group] ||= this.device._createBindGroupLayoutWebGPU(pipeline, group);
|
|
3641
|
+
return layoutCache[group];
|
|
3642
|
+
}
|
|
3643
|
+
_getEmptyBindGroup(bindGroupLayout, shaderLayout, group) {
|
|
3644
|
+
const layoutCache = this._getLayoutBindGroupCache(bindGroupLayout);
|
|
3645
|
+
layoutCache.emptyBindGroup ||= this.device._createBindGroupWebGPU(bindGroupLayout, shaderLayout, {}, group) || null;
|
|
3646
|
+
return layoutCache.emptyBindGroup;
|
|
3647
|
+
}
|
|
3648
|
+
_getLayoutBindGroupCache(bindGroupLayout) {
|
|
3649
|
+
let layoutCache = this._bindGroupCacheByLayout.get(bindGroupLayout);
|
|
3650
|
+
if (!layoutCache) {
|
|
3651
|
+
layoutCache = { bindGroupsBySource: /* @__PURE__ */ new WeakMap() };
|
|
3652
|
+
this._bindGroupCacheByLayout.set(bindGroupLayout, layoutCache);
|
|
3653
|
+
}
|
|
3654
|
+
return layoutCache;
|
|
3655
|
+
}
|
|
3656
|
+
};
|
|
3657
|
+
function _getDefaultBindGroupFactory(device) {
|
|
3658
|
+
device._factories.bindGroupFactory ||= new BindGroupFactory(device);
|
|
3659
|
+
return device._factories.bindGroupFactory;
|
|
3660
|
+
}
|
|
3661
|
+
function getBindGroupIndicesUpToMax(bindings) {
|
|
3662
|
+
const maxGroup = bindings.reduce((highestGroup, binding) => Math.max(highestGroup, binding.group), -1);
|
|
3663
|
+
return Array.from({ length: maxGroup + 1 }, (_, group) => group);
|
|
3664
|
+
}
|
|
3665
|
+
function hasBindingsInGroup(bindings, group) {
|
|
3666
|
+
return bindings.some((binding) => binding.group === group);
|
|
3667
|
+
}
|
|
3668
|
+
|
|
3669
|
+
// dist/adapter/resources/render-pass.js
|
|
3670
|
+
var _RenderPass = class extends Resource {
|
|
3671
|
+
get [Symbol.toStringTag]() {
|
|
3672
|
+
return "RenderPass";
|
|
3673
|
+
}
|
|
3674
|
+
constructor(device, props) {
|
|
3675
|
+
props = _RenderPass.normalizeProps(device, props);
|
|
3676
|
+
super(device, props, _RenderPass.defaultProps);
|
|
3677
|
+
}
|
|
3678
|
+
static normalizeProps(device, props) {
|
|
3679
|
+
return props;
|
|
3680
|
+
}
|
|
3681
|
+
};
|
|
3682
|
+
var RenderPass = _RenderPass;
|
|
3683
|
+
/** TODO - should be [0, 0, 0, 0], update once deck.gl tests run clean */
|
|
3684
|
+
__publicField(RenderPass, "defaultClearColor", [0, 0, 0, 1]);
|
|
3685
|
+
/** Depth 1.0 represents the far plance */
|
|
3686
|
+
__publicField(RenderPass, "defaultClearDepth", 1);
|
|
3687
|
+
/** Clears all stencil bits */
|
|
3688
|
+
__publicField(RenderPass, "defaultClearStencil", 0);
|
|
3689
|
+
/** Default properties for RenderPass */
|
|
3690
|
+
__publicField(RenderPass, "defaultProps", {
|
|
3691
|
+
...Resource.defaultProps,
|
|
3692
|
+
framebuffer: null,
|
|
3693
|
+
parameters: void 0,
|
|
3694
|
+
clearColor: _RenderPass.defaultClearColor,
|
|
3695
|
+
clearColors: void 0,
|
|
3696
|
+
clearDepth: _RenderPass.defaultClearDepth,
|
|
3697
|
+
clearStencil: _RenderPass.defaultClearStencil,
|
|
3698
|
+
depthReadOnly: false,
|
|
3699
|
+
stencilReadOnly: false,
|
|
3700
|
+
discard: false,
|
|
3701
|
+
occlusionQuerySet: void 0,
|
|
3702
|
+
timestampQuerySet: void 0,
|
|
3703
|
+
beginTimestampIndex: void 0,
|
|
3704
|
+
endTimestampIndex: void 0
|
|
3705
|
+
});
|
|
3706
|
+
|
|
3707
|
+
// dist/adapter/resources/compute-pass.js
|
|
3708
|
+
var _ComputePass = class extends Resource {
|
|
3709
|
+
constructor(device, props) {
|
|
3710
|
+
super(device, props, _ComputePass.defaultProps);
|
|
3711
|
+
}
|
|
3712
|
+
get [Symbol.toStringTag]() {
|
|
3713
|
+
return "ComputePass";
|
|
3714
|
+
}
|
|
3715
|
+
};
|
|
3716
|
+
var ComputePass = _ComputePass;
|
|
3717
|
+
__publicField(ComputePass, "defaultProps", {
|
|
3718
|
+
...Resource.defaultProps,
|
|
3719
|
+
timestampQuerySet: void 0,
|
|
3720
|
+
beginTimestampIndex: void 0,
|
|
3721
|
+
endTimestampIndex: void 0
|
|
3722
|
+
});
|
|
3723
|
+
|
|
3724
|
+
// dist/adapter/resources/command-encoder.js
|
|
3725
|
+
var _CommandEncoder = class extends Resource {
|
|
3726
|
+
get [Symbol.toStringTag]() {
|
|
3727
|
+
return "CommandEncoder";
|
|
3728
|
+
}
|
|
3729
|
+
_timeProfilingQuerySet = null;
|
|
3730
|
+
_timeProfilingSlotCount = 0;
|
|
3731
|
+
_gpuTimeMs;
|
|
3732
|
+
constructor(device, props) {
|
|
3733
|
+
super(device, props, _CommandEncoder.defaultProps);
|
|
3734
|
+
this._timeProfilingQuerySet = props.timeProfilingQuerySet ?? null;
|
|
3735
|
+
this._timeProfilingSlotCount = 0;
|
|
3736
|
+
this._gpuTimeMs = void 0;
|
|
3737
|
+
}
|
|
3738
|
+
/**
|
|
3739
|
+
* Reads all resolved timestamp pairs on the current profiler query set and caches the sum
|
|
3740
|
+
* as milliseconds on this encoder.
|
|
3741
|
+
*/
|
|
3742
|
+
async resolveTimeProfilingQuerySet() {
|
|
3743
|
+
this._gpuTimeMs = void 0;
|
|
3744
|
+
if (!this._timeProfilingQuerySet) {
|
|
3745
|
+
return;
|
|
3746
|
+
}
|
|
3747
|
+
const pairCount = Math.floor(this._timeProfilingSlotCount / 2);
|
|
3748
|
+
if (pairCount <= 0) {
|
|
3749
|
+
return;
|
|
3750
|
+
}
|
|
3751
|
+
const queryCount = pairCount * 2;
|
|
3752
|
+
const results = await this._timeProfilingQuerySet.readResults({
|
|
3753
|
+
firstQuery: 0,
|
|
3754
|
+
queryCount
|
|
3755
|
+
});
|
|
3756
|
+
let totalDurationNanoseconds = 0n;
|
|
3757
|
+
for (let queryIndex = 0; queryIndex < queryCount; queryIndex += 2) {
|
|
3758
|
+
totalDurationNanoseconds += results[queryIndex + 1] - results[queryIndex];
|
|
3759
|
+
}
|
|
3760
|
+
this._gpuTimeMs = Number(totalDurationNanoseconds) / 1e6;
|
|
3761
|
+
}
|
|
3762
|
+
/** Returns the number of query slots consumed by automatic pass profiling on this encoder. */
|
|
3763
|
+
getTimeProfilingSlotCount() {
|
|
3764
|
+
return this._timeProfilingSlotCount;
|
|
3765
|
+
}
|
|
3766
|
+
getTimeProfilingQuerySet() {
|
|
3767
|
+
return this._timeProfilingQuerySet;
|
|
3768
|
+
}
|
|
3769
|
+
/** Internal helper for auto-assigning timestamp slots to render/compute passes on this encoder. */
|
|
3770
|
+
_applyTimeProfilingToPassProps(props) {
|
|
3771
|
+
const passProps = props || {};
|
|
3772
|
+
if (!this._supportsTimestampQueries() || !this._timeProfilingQuerySet) {
|
|
3773
|
+
return passProps;
|
|
3774
|
+
}
|
|
3775
|
+
if (passProps.timestampQuerySet !== void 0 || passProps.beginTimestampIndex !== void 0 || passProps.endTimestampIndex !== void 0) {
|
|
3776
|
+
return passProps;
|
|
3777
|
+
}
|
|
3778
|
+
const beginTimestampIndex = this._timeProfilingSlotCount;
|
|
3779
|
+
if (beginTimestampIndex + 1 >= this._timeProfilingQuerySet.props.count) {
|
|
3780
|
+
return passProps;
|
|
3781
|
+
}
|
|
3782
|
+
this._timeProfilingSlotCount += 2;
|
|
3783
|
+
return {
|
|
3784
|
+
...passProps,
|
|
3785
|
+
timestampQuerySet: this._timeProfilingQuerySet,
|
|
3786
|
+
beginTimestampIndex,
|
|
3787
|
+
endTimestampIndex: beginTimestampIndex + 1
|
|
3788
|
+
};
|
|
3789
|
+
}
|
|
3790
|
+
_supportsTimestampQueries() {
|
|
3791
|
+
return this.device.features.has("timestamp-query");
|
|
3792
|
+
}
|
|
3793
|
+
};
|
|
3794
|
+
var CommandEncoder = _CommandEncoder;
|
|
3795
|
+
// TODO - luma.gl has these on the device, should we align with WebGPU API?
|
|
3796
|
+
// beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
|
|
3797
|
+
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
3798
|
+
__publicField(CommandEncoder, "defaultProps", {
|
|
3799
|
+
...Resource.defaultProps,
|
|
3800
|
+
measureExecutionTime: void 0,
|
|
3801
|
+
timeProfilingQuerySet: void 0
|
|
3802
|
+
});
|
|
3803
|
+
|
|
3804
|
+
// dist/adapter/resources/command-buffer.js
|
|
3805
|
+
var _CommandBuffer = class extends Resource {
|
|
3806
|
+
get [Symbol.toStringTag]() {
|
|
3807
|
+
return "CommandBuffer";
|
|
3808
|
+
}
|
|
3809
|
+
constructor(device, props) {
|
|
3810
|
+
super(device, props, _CommandBuffer.defaultProps);
|
|
3811
|
+
}
|
|
3812
|
+
};
|
|
2363
3813
|
var CommandBuffer = _CommandBuffer;
|
|
2364
3814
|
__publicField(CommandBuffer, "defaultProps", {
|
|
2365
3815
|
...Resource.defaultProps
|
|
2366
3816
|
});
|
|
2367
3817
|
|
|
2368
|
-
// dist/shadertypes/
|
|
3818
|
+
// dist/shadertypes/shader-types/shader-type-decoder.js
|
|
2369
3819
|
function getVariableShaderTypeInfo(format) {
|
|
2370
|
-
const
|
|
3820
|
+
const resolvedFormat = resolveVariableShaderTypeAlias(format);
|
|
3821
|
+
const decoded = UNIFORM_FORMATS[resolvedFormat];
|
|
3822
|
+
if (!decoded) {
|
|
3823
|
+
throw new Error(`Unsupported variable shader type: ${format}`);
|
|
3824
|
+
}
|
|
2371
3825
|
return decoded;
|
|
2372
3826
|
}
|
|
2373
3827
|
function getAttributeShaderTypeInfo(attributeType) {
|
|
2374
|
-
const
|
|
3828
|
+
const resolvedAttributeType = resolveAttributeShaderTypeAlias(attributeType);
|
|
3829
|
+
const decoded = TYPE_INFO[resolvedAttributeType];
|
|
3830
|
+
if (!decoded) {
|
|
3831
|
+
throw new Error(`Unsupported attribute shader type: ${attributeType}`);
|
|
3832
|
+
}
|
|
3833
|
+
const [primitiveType, components] = decoded;
|
|
2375
3834
|
const integer = primitiveType === "i32" || primitiveType === "u32";
|
|
2376
3835
|
const signed = primitiveType !== "u32";
|
|
2377
3836
|
const byteLength = PRIMITIVE_TYPE_SIZES[primitiveType] * components;
|
|
@@ -2383,6 +3842,33 @@ function getAttributeShaderTypeInfo(attributeType) {
|
|
|
2383
3842
|
signed
|
|
2384
3843
|
};
|
|
2385
3844
|
}
|
|
3845
|
+
var ShaderTypeDecoder = class {
|
|
3846
|
+
getVariableShaderTypeInfo(format) {
|
|
3847
|
+
return getVariableShaderTypeInfo(format);
|
|
3848
|
+
}
|
|
3849
|
+
getAttributeShaderTypeInfo(attributeType) {
|
|
3850
|
+
return getAttributeShaderTypeInfo(attributeType);
|
|
3851
|
+
}
|
|
3852
|
+
makeShaderAttributeType(primitiveType, components) {
|
|
3853
|
+
return makeShaderAttributeType(primitiveType, components);
|
|
3854
|
+
}
|
|
3855
|
+
resolveAttributeShaderTypeAlias(alias) {
|
|
3856
|
+
return resolveAttributeShaderTypeAlias(alias);
|
|
3857
|
+
}
|
|
3858
|
+
resolveVariableShaderTypeAlias(alias) {
|
|
3859
|
+
return resolveVariableShaderTypeAlias(alias);
|
|
3860
|
+
}
|
|
3861
|
+
};
|
|
3862
|
+
function makeShaderAttributeType(primitiveType, components) {
|
|
3863
|
+
return components === 1 ? primitiveType : `vec${components}<${primitiveType}>`;
|
|
3864
|
+
}
|
|
3865
|
+
function resolveAttributeShaderTypeAlias(alias) {
|
|
3866
|
+
return WGSL_ATTRIBUTE_TYPE_ALIAS_MAP[alias] || alias;
|
|
3867
|
+
}
|
|
3868
|
+
function resolveVariableShaderTypeAlias(alias) {
|
|
3869
|
+
return WGSL_VARIABLE_TYPE_ALIAS_MAP[alias] || alias;
|
|
3870
|
+
}
|
|
3871
|
+
var shaderTypeDecoder = new ShaderTypeDecoder();
|
|
2386
3872
|
var PRIMITIVE_TYPE_SIZES = {
|
|
2387
3873
|
f32: 4,
|
|
2388
3874
|
f16: 2,
|
|
@@ -2479,7 +3965,18 @@ var WGSL_ATTRIBUTE_TYPE_ALIAS_MAP = {
|
|
|
2479
3965
|
vec4h: "vec4<f16>"
|
|
2480
3966
|
};
|
|
2481
3967
|
var WGSL_VARIABLE_TYPE_ALIAS_MAP = {
|
|
2482
|
-
|
|
3968
|
+
vec2i: "vec2<i32>",
|
|
3969
|
+
vec3i: "vec3<i32>",
|
|
3970
|
+
vec4i: "vec4<i32>",
|
|
3971
|
+
vec2u: "vec2<u32>",
|
|
3972
|
+
vec3u: "vec3<u32>",
|
|
3973
|
+
vec4u: "vec4<u32>",
|
|
3974
|
+
vec2f: "vec2<f32>",
|
|
3975
|
+
vec3f: "vec3<f32>",
|
|
3976
|
+
vec4f: "vec4<f32>",
|
|
3977
|
+
vec2h: "vec2<f16>",
|
|
3978
|
+
vec3h: "vec3<f16>",
|
|
3979
|
+
vec4h: "vec4<f16>",
|
|
2483
3980
|
mat2x2f: "mat2x2<f32>",
|
|
2484
3981
|
mat2x3f: "mat2x3<f32>",
|
|
2485
3982
|
mat2x4f: "mat2x4<f32>",
|
|
@@ -2543,10 +4040,10 @@ function getAttributeInfoFromLayouts(shaderLayout, bufferLayout, name2) {
|
|
|
2543
4040
|
if (!shaderDeclaration) {
|
|
2544
4041
|
return null;
|
|
2545
4042
|
}
|
|
2546
|
-
const attributeTypeInfo = getAttributeShaderTypeInfo(shaderDeclaration.type);
|
|
2547
|
-
const defaultVertexFormat = getCompatibleVertexFormat(attributeTypeInfo);
|
|
4043
|
+
const attributeTypeInfo = shaderTypeDecoder.getAttributeShaderTypeInfo(shaderDeclaration.type);
|
|
4044
|
+
const defaultVertexFormat = vertexFormatDecoder.getCompatibleVertexFormat(attributeTypeInfo);
|
|
2548
4045
|
const vertexFormat = (bufferMapping == null ? void 0 : bufferMapping.vertexFormat) || defaultVertexFormat;
|
|
2549
|
-
const vertexFormatInfo = getVertexFormatInfo(vertexFormat);
|
|
4046
|
+
const vertexFormatInfo = vertexFormatDecoder.getVertexFormatInfo(vertexFormat);
|
|
2550
4047
|
return {
|
|
2551
4048
|
attributeName: (bufferMapping == null ? void 0 : bufferMapping.attributeName) || shaderDeclaration.name,
|
|
2552
4049
|
bufferName: (bufferMapping == null ? void 0 : bufferMapping.bufferName) || shaderDeclaration.name,
|
|
@@ -2615,7 +4112,7 @@ function getAttributeFromAttributesList(bufferLayouts, name2) {
|
|
|
2615
4112
|
let byteStride = bufferLayout.byteStride;
|
|
2616
4113
|
if (typeof bufferLayout.byteStride !== "number") {
|
|
2617
4114
|
for (const attributeMapping2 of bufferLayout.attributes || []) {
|
|
2618
|
-
const info = getVertexFormatInfo(attributeMapping2.format);
|
|
4115
|
+
const info = vertexFormatDecoder.getVertexFormatInfo(attributeMapping2.format);
|
|
2619
4116
|
byteStride += info.byteLength;
|
|
2620
4117
|
}
|
|
2621
4118
|
}
|
|
@@ -2699,6 +4196,20 @@ __publicField(QuerySet, "defaultProps", {
|
|
|
2699
4196
|
count: void 0
|
|
2700
4197
|
});
|
|
2701
4198
|
|
|
4199
|
+
// dist/adapter/resources/fence.js
|
|
4200
|
+
var _Fence = class extends Resource {
|
|
4201
|
+
get [Symbol.toStringTag]() {
|
|
4202
|
+
return "Fence";
|
|
4203
|
+
}
|
|
4204
|
+
constructor(device, props = {}) {
|
|
4205
|
+
super(device, props, _Fence.defaultProps);
|
|
4206
|
+
}
|
|
4207
|
+
};
|
|
4208
|
+
var Fence = _Fence;
|
|
4209
|
+
__publicField(Fence, "defaultProps", {
|
|
4210
|
+
...Resource.defaultProps
|
|
4211
|
+
});
|
|
4212
|
+
|
|
2702
4213
|
// dist/adapter/resources/pipeline-layout.js
|
|
2703
4214
|
var _PipelineLayout = class extends Resource {
|
|
2704
4215
|
get [Symbol.toStringTag]() {
|
|
@@ -2717,6 +4228,190 @@ __publicField(PipelineLayout, "defaultProps", {
|
|
|
2717
4228
|
}
|
|
2718
4229
|
});
|
|
2719
4230
|
|
|
4231
|
+
// dist/shadertypes/data-types/decode-data-types.js
|
|
4232
|
+
function alignTo(size, count) {
|
|
4233
|
+
switch (count) {
|
|
4234
|
+
case 1:
|
|
4235
|
+
return size;
|
|
4236
|
+
case 2:
|
|
4237
|
+
return size + size % 2;
|
|
4238
|
+
default:
|
|
4239
|
+
return size + (4 - size % 4) % 4;
|
|
4240
|
+
}
|
|
4241
|
+
}
|
|
4242
|
+
function getTypedArrayConstructor(type) {
|
|
4243
|
+
const [, , , , Constructor] = NORMALIZED_TYPE_MAP2[type];
|
|
4244
|
+
return Constructor;
|
|
4245
|
+
}
|
|
4246
|
+
var NORMALIZED_TYPE_MAP2 = {
|
|
4247
|
+
uint8: ["uint8", "u32", 1, false, Uint8Array],
|
|
4248
|
+
sint8: ["sint8", "i32", 1, false, Int8Array],
|
|
4249
|
+
unorm8: ["uint8", "f32", 1, true, Uint8Array],
|
|
4250
|
+
snorm8: ["sint8", "f32", 1, true, Int8Array],
|
|
4251
|
+
uint16: ["uint16", "u32", 2, false, Uint16Array],
|
|
4252
|
+
sint16: ["sint16", "i32", 2, false, Int16Array],
|
|
4253
|
+
unorm16: ["uint16", "u32", 2, true, Uint16Array],
|
|
4254
|
+
snorm16: ["sint16", "i32", 2, true, Int16Array],
|
|
4255
|
+
float16: ["float16", "f16", 2, false, Uint16Array],
|
|
4256
|
+
float32: ["float32", "f32", 4, false, Float32Array],
|
|
4257
|
+
uint32: ["uint32", "u32", 4, false, Uint32Array],
|
|
4258
|
+
sint32: ["sint32", "i32", 4, false, Int32Array]
|
|
4259
|
+
};
|
|
4260
|
+
|
|
4261
|
+
// dist/shadertypes/shader-types/shader-block-layout.js
|
|
4262
|
+
function makeShaderBlockLayout(uniformTypes, options = {}) {
|
|
4263
|
+
const copiedUniformTypes = { ...uniformTypes };
|
|
4264
|
+
const layout = options.layout ?? "std140";
|
|
4265
|
+
const fields = {};
|
|
4266
|
+
let size = 0;
|
|
4267
|
+
for (const [key, uniformType] of Object.entries(copiedUniformTypes)) {
|
|
4268
|
+
size = addToLayout(fields, key, uniformType, size, layout);
|
|
4269
|
+
}
|
|
4270
|
+
size = alignTo(size, getTypeAlignment(copiedUniformTypes, layout));
|
|
4271
|
+
return {
|
|
4272
|
+
layout,
|
|
4273
|
+
byteLength: size * 4,
|
|
4274
|
+
uniformTypes: copiedUniformTypes,
|
|
4275
|
+
fields
|
|
4276
|
+
};
|
|
4277
|
+
}
|
|
4278
|
+
function getLeafLayoutInfo(type, layout) {
|
|
4279
|
+
const resolvedType = resolveVariableShaderTypeAlias(type);
|
|
4280
|
+
const decodedType = getVariableShaderTypeInfo(resolvedType);
|
|
4281
|
+
const matrixMatch = /^mat(\d)x(\d)<.+>$/.exec(resolvedType);
|
|
4282
|
+
if (matrixMatch) {
|
|
4283
|
+
const columns = Number(matrixMatch[1]);
|
|
4284
|
+
const rows = Number(matrixMatch[2]);
|
|
4285
|
+
const columnInfo = getVectorLayoutInfo(rows, resolvedType, decodedType.type, layout);
|
|
4286
|
+
const columnStride = getMatrixColumnStride(columnInfo.size, columnInfo.alignment, layout);
|
|
4287
|
+
return {
|
|
4288
|
+
alignment: columnInfo.alignment,
|
|
4289
|
+
size: columns * columnStride,
|
|
4290
|
+
components: columns * rows,
|
|
4291
|
+
columns,
|
|
4292
|
+
rows,
|
|
4293
|
+
columnStride,
|
|
4294
|
+
shaderType: resolvedType,
|
|
4295
|
+
type: decodedType.type
|
|
4296
|
+
};
|
|
4297
|
+
}
|
|
4298
|
+
const vectorMatch = /^vec(\d)<.+>$/.exec(resolvedType);
|
|
4299
|
+
if (vectorMatch) {
|
|
4300
|
+
return getVectorLayoutInfo(Number(vectorMatch[1]), resolvedType, decodedType.type, layout);
|
|
4301
|
+
}
|
|
4302
|
+
return {
|
|
4303
|
+
alignment: 1,
|
|
4304
|
+
size: 1,
|
|
4305
|
+
components: 1,
|
|
4306
|
+
columns: 1,
|
|
4307
|
+
rows: 1,
|
|
4308
|
+
columnStride: 1,
|
|
4309
|
+
shaderType: resolvedType,
|
|
4310
|
+
type: decodedType.type
|
|
4311
|
+
};
|
|
4312
|
+
}
|
|
4313
|
+
function isCompositeShaderTypeStruct(value) {
|
|
4314
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4315
|
+
}
|
|
4316
|
+
function addToLayout(fields, name2, type, offset, layout) {
|
|
4317
|
+
if (typeof type === "string") {
|
|
4318
|
+
const info = getLeafLayoutInfo(type, layout);
|
|
4319
|
+
const alignedOffset = alignTo(offset, info.alignment);
|
|
4320
|
+
fields[name2] = {
|
|
4321
|
+
offset: alignedOffset,
|
|
4322
|
+
...info
|
|
4323
|
+
};
|
|
4324
|
+
return alignedOffset + info.size;
|
|
4325
|
+
}
|
|
4326
|
+
if (Array.isArray(type)) {
|
|
4327
|
+
if (Array.isArray(type[0])) {
|
|
4328
|
+
throw new Error(`Nested arrays are not supported for ${name2}`);
|
|
4329
|
+
}
|
|
4330
|
+
const elementType = type[0];
|
|
4331
|
+
const length = type[1];
|
|
4332
|
+
const stride = getArrayStride(elementType, layout);
|
|
4333
|
+
const arrayOffset = alignTo(offset, getTypeAlignment(type, layout));
|
|
4334
|
+
for (let i = 0; i < length; i++) {
|
|
4335
|
+
addToLayout(fields, `${name2}[${i}]`, elementType, arrayOffset + i * stride, layout);
|
|
4336
|
+
}
|
|
4337
|
+
return arrayOffset + stride * length;
|
|
4338
|
+
}
|
|
4339
|
+
if (isCompositeShaderTypeStruct(type)) {
|
|
4340
|
+
const structAlignment = getTypeAlignment(type, layout);
|
|
4341
|
+
let structOffset = alignTo(offset, structAlignment);
|
|
4342
|
+
for (const [memberName, memberType] of Object.entries(type)) {
|
|
4343
|
+
structOffset = addToLayout(fields, `${name2}.${memberName}`, memberType, structOffset, layout);
|
|
4344
|
+
}
|
|
4345
|
+
return alignTo(structOffset, structAlignment);
|
|
4346
|
+
}
|
|
4347
|
+
throw new Error(`Unsupported CompositeShaderType for ${name2}`);
|
|
4348
|
+
}
|
|
4349
|
+
function getTypeSize(type, layout) {
|
|
4350
|
+
if (typeof type === "string") {
|
|
4351
|
+
return getLeafLayoutInfo(type, layout).size;
|
|
4352
|
+
}
|
|
4353
|
+
if (Array.isArray(type)) {
|
|
4354
|
+
const elementType = type[0];
|
|
4355
|
+
const length = type[1];
|
|
4356
|
+
if (Array.isArray(elementType)) {
|
|
4357
|
+
throw new Error("Nested arrays are not supported");
|
|
4358
|
+
}
|
|
4359
|
+
return getArrayStride(elementType, layout) * length;
|
|
4360
|
+
}
|
|
4361
|
+
let size = 0;
|
|
4362
|
+
for (const memberType of Object.values(type)) {
|
|
4363
|
+
const compositeMemberType = memberType;
|
|
4364
|
+
size = alignTo(size, getTypeAlignment(compositeMemberType, layout));
|
|
4365
|
+
size += getTypeSize(compositeMemberType, layout);
|
|
4366
|
+
}
|
|
4367
|
+
return alignTo(size, getTypeAlignment(type, layout));
|
|
4368
|
+
}
|
|
4369
|
+
function getTypeAlignment(type, layout) {
|
|
4370
|
+
if (typeof type === "string") {
|
|
4371
|
+
return getLeafLayoutInfo(type, layout).alignment;
|
|
4372
|
+
}
|
|
4373
|
+
if (Array.isArray(type)) {
|
|
4374
|
+
const elementType = type[0];
|
|
4375
|
+
const elementAlignment = getTypeAlignment(elementType, layout);
|
|
4376
|
+
return uses16ByteArrayAlignment(layout) ? Math.max(elementAlignment, 4) : elementAlignment;
|
|
4377
|
+
}
|
|
4378
|
+
let maxAlignment = 1;
|
|
4379
|
+
for (const memberType of Object.values(type)) {
|
|
4380
|
+
const memberAlignment = getTypeAlignment(memberType, layout);
|
|
4381
|
+
maxAlignment = Math.max(maxAlignment, memberAlignment);
|
|
4382
|
+
}
|
|
4383
|
+
return uses16ByteStructAlignment(layout) ? Math.max(maxAlignment, 4) : maxAlignment;
|
|
4384
|
+
}
|
|
4385
|
+
function getVectorLayoutInfo(components, shaderType, type, layout) {
|
|
4386
|
+
return {
|
|
4387
|
+
alignment: components === 2 ? 2 : 4,
|
|
4388
|
+
size: components === 3 ? 3 : components,
|
|
4389
|
+
components,
|
|
4390
|
+
columns: 1,
|
|
4391
|
+
rows: components,
|
|
4392
|
+
columnStride: components === 3 ? 3 : components,
|
|
4393
|
+
shaderType,
|
|
4394
|
+
type
|
|
4395
|
+
};
|
|
4396
|
+
}
|
|
4397
|
+
function getArrayStride(elementType, layout) {
|
|
4398
|
+
const elementSize = getTypeSize(elementType, layout);
|
|
4399
|
+
const elementAlignment = getTypeAlignment(elementType, layout);
|
|
4400
|
+
return getArrayLikeStride(elementSize, elementAlignment, layout);
|
|
4401
|
+
}
|
|
4402
|
+
function getArrayLikeStride(size, alignment, layout) {
|
|
4403
|
+
return alignTo(size, uses16ByteArrayAlignment(layout) ? 4 : alignment);
|
|
4404
|
+
}
|
|
4405
|
+
function getMatrixColumnStride(size, alignment, layout) {
|
|
4406
|
+
return layout === "std140" ? 4 : alignTo(size, alignment);
|
|
4407
|
+
}
|
|
4408
|
+
function uses16ByteArrayAlignment(layout) {
|
|
4409
|
+
return layout === "std140" || layout === "wgsl-uniform";
|
|
4410
|
+
}
|
|
4411
|
+
function uses16ByteStructAlignment(layout) {
|
|
4412
|
+
return layout === "std140" || layout === "wgsl-uniform";
|
|
4413
|
+
}
|
|
4414
|
+
|
|
2720
4415
|
// dist/utils/array-utils-flat.js
|
|
2721
4416
|
var arrayBuffer;
|
|
2722
4417
|
function getScratchArrayBuffer(byteLength) {
|
|
@@ -2741,88 +4436,192 @@ function isNumberArray(value) {
|
|
|
2741
4436
|
return isTypedArray(value);
|
|
2742
4437
|
}
|
|
2743
4438
|
|
|
2744
|
-
// dist/portable/
|
|
2745
|
-
var
|
|
2746
|
-
|
|
2747
|
-
layout
|
|
2748
|
-
/**
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
constructor(
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
4439
|
+
// dist/portable/shader-block-writer.js
|
|
4440
|
+
var ShaderBlockWriter = class {
|
|
4441
|
+
/** Layout metadata used to flatten and serialize values. */
|
|
4442
|
+
layout;
|
|
4443
|
+
/**
|
|
4444
|
+
* Creates a writer for a precomputed shader-block layout.
|
|
4445
|
+
*/
|
|
4446
|
+
constructor(layout) {
|
|
4447
|
+
this.layout = layout;
|
|
4448
|
+
}
|
|
4449
|
+
/**
|
|
4450
|
+
* Returns `true` if the flattened layout contains the given field.
|
|
4451
|
+
*/
|
|
4452
|
+
has(name2) {
|
|
4453
|
+
return Boolean(this.layout.fields[name2]);
|
|
4454
|
+
}
|
|
4455
|
+
/**
|
|
4456
|
+
* Returns offset and size metadata for a flattened field.
|
|
4457
|
+
*/
|
|
4458
|
+
get(name2) {
|
|
4459
|
+
const entry = this.layout.fields[name2];
|
|
4460
|
+
return entry ? { offset: entry.offset, size: entry.size } : void 0;
|
|
4461
|
+
}
|
|
4462
|
+
/**
|
|
4463
|
+
* Flattens nested composite values into leaf-path values understood by {@link UniformBlock}.
|
|
4464
|
+
*
|
|
4465
|
+
* Top-level values may be supplied either in nested object form matching the
|
|
4466
|
+
* declared composite shader types or as already-flattened leaf-path values.
|
|
4467
|
+
*/
|
|
4468
|
+
getFlatUniformValues(uniformValues) {
|
|
4469
|
+
const flattenedUniformValues = {};
|
|
4470
|
+
for (const [name2, value] of Object.entries(uniformValues)) {
|
|
4471
|
+
const uniformType = this.layout.uniformTypes[name2];
|
|
4472
|
+
if (uniformType) {
|
|
4473
|
+
this._flattenCompositeValue(flattenedUniformValues, name2, uniformType, value);
|
|
4474
|
+
} else if (this.layout.fields[name2]) {
|
|
4475
|
+
flattenedUniformValues[name2] = value;
|
|
4476
|
+
}
|
|
4477
|
+
}
|
|
4478
|
+
return flattenedUniformValues;
|
|
4479
|
+
}
|
|
4480
|
+
/**
|
|
4481
|
+
* Serializes the supplied values into buffer-backed binary data.
|
|
4482
|
+
*
|
|
4483
|
+
* The returned view length matches {@link ShaderBlockLayout.byteLength}, which
|
|
4484
|
+
* is the exact packed size of the block.
|
|
4485
|
+
*/
|
|
2767
4486
|
getData(uniformValues) {
|
|
2768
|
-
const
|
|
4487
|
+
const buffer = getScratchArrayBuffer(this.layout.byteLength);
|
|
4488
|
+
new Uint8Array(buffer, 0, this.layout.byteLength).fill(0);
|
|
2769
4489
|
const typedArrays = {
|
|
2770
|
-
i32: new Int32Array(
|
|
2771
|
-
u32: new Uint32Array(
|
|
2772
|
-
f32: new Float32Array(
|
|
2773
|
-
|
|
2774
|
-
f16: new Uint16Array(arrayBuffer2)
|
|
4490
|
+
i32: new Int32Array(buffer),
|
|
4491
|
+
u32: new Uint32Array(buffer),
|
|
4492
|
+
f32: new Float32Array(buffer),
|
|
4493
|
+
f16: new Uint16Array(buffer)
|
|
2775
4494
|
};
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
4495
|
+
const flattenedUniformValues = this.getFlatUniformValues(uniformValues);
|
|
4496
|
+
for (const [name2, value] of Object.entries(flattenedUniformValues)) {
|
|
4497
|
+
this._writeLeafValue(typedArrays, name2, value);
|
|
4498
|
+
}
|
|
4499
|
+
return new Uint8Array(buffer, 0, this.layout.byteLength);
|
|
4500
|
+
}
|
|
4501
|
+
/**
|
|
4502
|
+
* Recursively flattens nested values using the declared composite shader type.
|
|
4503
|
+
*/
|
|
4504
|
+
_flattenCompositeValue(flattenedUniformValues, baseName, uniformType, value) {
|
|
4505
|
+
if (value === void 0) {
|
|
4506
|
+
return;
|
|
4507
|
+
}
|
|
4508
|
+
if (typeof uniformType === "string" || this.layout.fields[baseName]) {
|
|
4509
|
+
flattenedUniformValues[baseName] = value;
|
|
4510
|
+
return;
|
|
4511
|
+
}
|
|
4512
|
+
if (Array.isArray(uniformType)) {
|
|
4513
|
+
const elementType = uniformType[0];
|
|
4514
|
+
const length = uniformType[1];
|
|
4515
|
+
if (Array.isArray(elementType)) {
|
|
4516
|
+
throw new Error(`Nested arrays are not supported for ${baseName}`);
|
|
4517
|
+
}
|
|
4518
|
+
if (typeof elementType === "string" && isNumberArray(value)) {
|
|
4519
|
+
this._flattenPackedArray(flattenedUniformValues, baseName, elementType, length, value);
|
|
4520
|
+
return;
|
|
4521
|
+
}
|
|
4522
|
+
if (!Array.isArray(value)) {
|
|
4523
|
+
log.warn(`Unsupported uniform array value for ${baseName}:`, value)();
|
|
4524
|
+
return;
|
|
2781
4525
|
}
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
if (typeof value !== "number" && typeof value !== "boolean") {
|
|
2786
|
-
log.warn(`Supplied value for single component uniform ${name2} is not a number: ${value}`)();
|
|
4526
|
+
for (let index = 0; index < Math.min(value.length, length); index++) {
|
|
4527
|
+
const elementValue = value[index];
|
|
4528
|
+
if (elementValue === void 0) {
|
|
2787
4529
|
continue;
|
|
2788
4530
|
}
|
|
2789
|
-
|
|
2790
|
-
}
|
|
2791
|
-
|
|
2792
|
-
|
|
4531
|
+
this._flattenCompositeValue(flattenedUniformValues, `${baseName}[${index}]`, elementType, elementValue);
|
|
4532
|
+
}
|
|
4533
|
+
return;
|
|
4534
|
+
}
|
|
4535
|
+
if (isCompositeShaderTypeStruct(uniformType) && isCompositeUniformObject(value)) {
|
|
4536
|
+
for (const [key, subValue] of Object.entries(value)) {
|
|
4537
|
+
if (subValue === void 0) {
|
|
2793
4538
|
continue;
|
|
2794
4539
|
}
|
|
2795
|
-
|
|
4540
|
+
const nestedName = `${baseName}.${key}`;
|
|
4541
|
+
this._flattenCompositeValue(flattenedUniformValues, nestedName, uniformType[key], subValue);
|
|
2796
4542
|
}
|
|
4543
|
+
return;
|
|
2797
4544
|
}
|
|
2798
|
-
|
|
4545
|
+
log.warn(`Unsupported uniform value for ${baseName}:`, value)();
|
|
2799
4546
|
}
|
|
2800
|
-
/**
|
|
2801
|
-
|
|
2802
|
-
|
|
4547
|
+
/**
|
|
4548
|
+
* Expands tightly packed numeric arrays into per-element leaf fields.
|
|
4549
|
+
*/
|
|
4550
|
+
_flattenPackedArray(flattenedUniformValues, baseName, elementType, length, value) {
|
|
4551
|
+
const numericValue = value;
|
|
4552
|
+
const elementLayout = getLeafLayoutInfo(elementType, this.layout.layout);
|
|
4553
|
+
const packedElementLength = elementLayout.components;
|
|
4554
|
+
for (let index = 0; index < length; index++) {
|
|
4555
|
+
const start = index * packedElementLength;
|
|
4556
|
+
if (start >= numericValue.length) {
|
|
4557
|
+
break;
|
|
4558
|
+
}
|
|
4559
|
+
if (packedElementLength === 1) {
|
|
4560
|
+
flattenedUniformValues[`${baseName}[${index}]`] = Number(numericValue[start]);
|
|
4561
|
+
} else {
|
|
4562
|
+
flattenedUniformValues[`${baseName}[${index}]`] = sliceNumericArray(value, start, start + packedElementLength);
|
|
4563
|
+
}
|
|
4564
|
+
}
|
|
2803
4565
|
}
|
|
2804
|
-
/**
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
4566
|
+
/**
|
|
4567
|
+
* Writes one flattened leaf value into its typed-array view.
|
|
4568
|
+
*/
|
|
4569
|
+
_writeLeafValue(typedArrays, name2, value) {
|
|
4570
|
+
const entry = this.layout.fields[name2];
|
|
4571
|
+
if (!entry) {
|
|
4572
|
+
log.warn(`Uniform ${name2} not found in layout`)();
|
|
4573
|
+
return;
|
|
4574
|
+
}
|
|
4575
|
+
const { type, components, columns, rows, offset, columnStride } = entry;
|
|
4576
|
+
const array = typedArrays[type];
|
|
4577
|
+
if (components === 1) {
|
|
4578
|
+
array[offset] = Number(value);
|
|
4579
|
+
return;
|
|
4580
|
+
}
|
|
4581
|
+
const sourceValue = value;
|
|
4582
|
+
if (columns === 1) {
|
|
4583
|
+
for (let componentIndex = 0; componentIndex < components; componentIndex++) {
|
|
4584
|
+
array[offset + componentIndex] = Number(sourceValue[componentIndex] ?? 0);
|
|
4585
|
+
}
|
|
4586
|
+
return;
|
|
4587
|
+
}
|
|
4588
|
+
let sourceIndex = 0;
|
|
4589
|
+
for (let columnIndex = 0; columnIndex < columns; columnIndex++) {
|
|
4590
|
+
const columnOffset = offset + columnIndex * columnStride;
|
|
4591
|
+
for (let rowIndex = 0; rowIndex < rows; rowIndex++) {
|
|
4592
|
+
array[columnOffset + rowIndex] = Number(sourceValue[sourceIndex++] ?? 0);
|
|
4593
|
+
}
|
|
4594
|
+
}
|
|
2808
4595
|
}
|
|
2809
4596
|
};
|
|
4597
|
+
function isCompositeUniformObject(value) {
|
|
4598
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value) && !ArrayBuffer.isView(value);
|
|
4599
|
+
}
|
|
4600
|
+
function sliceNumericArray(value, start, end) {
|
|
4601
|
+
return Array.prototype.slice.call(value, start, end);
|
|
4602
|
+
}
|
|
2810
4603
|
|
|
2811
4604
|
// dist/utils/array-equal.js
|
|
4605
|
+
var MAX_ELEMENTWISE_ARRAY_COMPARE_LENGTH = 128;
|
|
2812
4606
|
function arrayEqual(a, b, limit = 16) {
|
|
2813
|
-
if (a
|
|
2814
|
-
return
|
|
4607
|
+
if (a === b) {
|
|
4608
|
+
return true;
|
|
2815
4609
|
}
|
|
2816
4610
|
const arrayA = a;
|
|
2817
4611
|
const arrayB = b;
|
|
2818
|
-
if (!isNumberArray(arrayA)) {
|
|
4612
|
+
if (!isNumberArray(arrayA) || !isNumberArray(arrayB)) {
|
|
2819
4613
|
return false;
|
|
2820
4614
|
}
|
|
2821
|
-
if (
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
4615
|
+
if (arrayA.length !== arrayB.length) {
|
|
4616
|
+
return false;
|
|
4617
|
+
}
|
|
4618
|
+
const maxCompareLength = Math.min(limit, MAX_ELEMENTWISE_ARRAY_COMPARE_LENGTH);
|
|
4619
|
+
if (arrayA.length > maxCompareLength) {
|
|
4620
|
+
return false;
|
|
4621
|
+
}
|
|
4622
|
+
for (let i = 0; i < arrayA.length; ++i) {
|
|
4623
|
+
if (arrayB[i] !== arrayA[i]) {
|
|
4624
|
+
return false;
|
|
2826
4625
|
}
|
|
2827
4626
|
}
|
|
2828
4627
|
return true;
|
|
@@ -2886,24 +4685,33 @@ var UniformBlock = class {
|
|
|
2886
4685
|
};
|
|
2887
4686
|
|
|
2888
4687
|
// dist/portable/uniform-store.js
|
|
4688
|
+
var minUniformBufferSize = 1024;
|
|
2889
4689
|
var UniformStore = class {
|
|
4690
|
+
/** Device used to infer layout and allocate buffers. */
|
|
4691
|
+
device;
|
|
2890
4692
|
/** Stores the uniform values for each uniform block */
|
|
2891
4693
|
uniformBlocks = /* @__PURE__ */ new Map();
|
|
2892
|
-
/**
|
|
2893
|
-
|
|
4694
|
+
/** Flattened layout metadata for each block. */
|
|
4695
|
+
shaderBlockLayouts = /* @__PURE__ */ new Map();
|
|
4696
|
+
/** Serializers for block-backed uniform data. */
|
|
4697
|
+
shaderBlockWriters = /* @__PURE__ */ new Map();
|
|
2894
4698
|
/** Actual buffer for the blocks */
|
|
2895
4699
|
uniformBuffers = /* @__PURE__ */ new Map();
|
|
2896
4700
|
/**
|
|
2897
|
-
*
|
|
2898
|
-
* @param blocks
|
|
4701
|
+
* Creates a new {@link UniformStore} for the supplied device and block definitions.
|
|
2899
4702
|
*/
|
|
2900
|
-
constructor(blocks) {
|
|
4703
|
+
constructor(device, blocks) {
|
|
4704
|
+
this.device = device;
|
|
2901
4705
|
for (const [bufferName, block] of Object.entries(blocks)) {
|
|
2902
4706
|
const uniformBufferName = bufferName;
|
|
2903
|
-
const
|
|
2904
|
-
|
|
4707
|
+
const shaderBlockLayout = makeShaderBlockLayout(block.uniformTypes ?? {}, {
|
|
4708
|
+
layout: block.layout ?? getDefaultUniformBufferLayout(device)
|
|
4709
|
+
});
|
|
4710
|
+
const shaderBlockWriter = new ShaderBlockWriter(shaderBlockLayout);
|
|
4711
|
+
this.shaderBlockLayouts.set(uniformBufferName, shaderBlockLayout);
|
|
4712
|
+
this.shaderBlockWriters.set(uniformBufferName, shaderBlockWriter);
|
|
2905
4713
|
const uniformBlock = new UniformBlock({ name: bufferName });
|
|
2906
|
-
uniformBlock.setUniforms(block.defaultUniforms || {});
|
|
4714
|
+
uniformBlock.setUniforms(shaderBlockWriter.getFlatUniformValues(block.defaultUniforms || {}));
|
|
2907
4715
|
this.uniformBlocks.set(uniformBufferName, uniformBlock);
|
|
2908
4716
|
}
|
|
2909
4717
|
}
|
|
@@ -2915,36 +4723,52 @@ var UniformStore = class {
|
|
|
2915
4723
|
}
|
|
2916
4724
|
/**
|
|
2917
4725
|
* Set uniforms
|
|
2918
|
-
*
|
|
4726
|
+
*
|
|
4727
|
+
* Makes all group properties partial and eagerly propagates changes to any
|
|
4728
|
+
* managed GPU buffers.
|
|
2919
4729
|
*/
|
|
2920
4730
|
setUniforms(uniforms) {
|
|
2921
4731
|
var _a;
|
|
2922
4732
|
for (const [blockName, uniformValues] of Object.entries(uniforms)) {
|
|
2923
|
-
|
|
4733
|
+
const uniformBufferName = blockName;
|
|
4734
|
+
const shaderBlockWriter = this.shaderBlockWriters.get(uniformBufferName);
|
|
4735
|
+
const flattenedUniforms = shaderBlockWriter == null ? void 0 : shaderBlockWriter.getFlatUniformValues(uniformValues || {});
|
|
4736
|
+
(_a = this.uniformBlocks.get(uniformBufferName)) == null ? void 0 : _a.setUniforms(flattenedUniforms || {});
|
|
2924
4737
|
}
|
|
2925
4738
|
this.updateUniformBuffers();
|
|
2926
4739
|
}
|
|
2927
|
-
/**
|
|
4740
|
+
/**
|
|
4741
|
+
* Returns the allocation size for the named uniform buffer.
|
|
4742
|
+
*
|
|
4743
|
+
* This may exceed the packed layout size because minimum buffer-size policy is
|
|
4744
|
+
* applied at the store layer.
|
|
4745
|
+
*/
|
|
2928
4746
|
getUniformBufferByteLength(uniformBufferName) {
|
|
2929
4747
|
var _a;
|
|
2930
|
-
|
|
4748
|
+
const packedByteLength = ((_a = this.shaderBlockLayouts.get(uniformBufferName)) == null ? void 0 : _a.byteLength) || 0;
|
|
4749
|
+
return Math.max(packedByteLength, minUniformBufferSize);
|
|
2931
4750
|
}
|
|
2932
|
-
/**
|
|
4751
|
+
/**
|
|
4752
|
+
* Returns packed binary data that can be uploaded to the named uniform buffer.
|
|
4753
|
+
*
|
|
4754
|
+
* The returned view length matches the packed block size and is not padded to
|
|
4755
|
+
* the store's minimum allocation size.
|
|
4756
|
+
*/
|
|
2933
4757
|
getUniformBufferData(uniformBufferName) {
|
|
2934
|
-
var _a
|
|
4758
|
+
var _a;
|
|
2935
4759
|
const uniformValues = ((_a = this.uniformBlocks.get(uniformBufferName)) == null ? void 0 : _a.getAllUniforms()) || {};
|
|
2936
|
-
|
|
4760
|
+
const shaderBlockWriter = this.shaderBlockWriters.get(uniformBufferName);
|
|
4761
|
+
return (shaderBlockWriter == null ? void 0 : shaderBlockWriter.getData(uniformValues)) || new Uint8Array(0);
|
|
2937
4762
|
}
|
|
2938
4763
|
/**
|
|
2939
|
-
* Creates an unmanaged uniform buffer
|
|
2940
|
-
* The new buffer is initialized with current / supplied values
|
|
4764
|
+
* Creates an unmanaged uniform buffer initialized with the current or supplied values.
|
|
2941
4765
|
*/
|
|
2942
|
-
createUniformBuffer(
|
|
4766
|
+
createUniformBuffer(uniformBufferName, uniforms) {
|
|
2943
4767
|
if (uniforms) {
|
|
2944
4768
|
this.setUniforms(uniforms);
|
|
2945
4769
|
}
|
|
2946
4770
|
const byteLength = this.getUniformBufferByteLength(uniformBufferName);
|
|
2947
|
-
const uniformBuffer = device.createBuffer({
|
|
4771
|
+
const uniformBuffer = this.device.createBuffer({
|
|
2948
4772
|
usage: Buffer2.UNIFORM | Buffer2.COPY_DST,
|
|
2949
4773
|
byteLength
|
|
2950
4774
|
});
|
|
@@ -2952,11 +4776,11 @@ var UniformStore = class {
|
|
|
2952
4776
|
uniformBuffer.write(uniformBufferData);
|
|
2953
4777
|
return uniformBuffer;
|
|
2954
4778
|
}
|
|
2955
|
-
/**
|
|
2956
|
-
getManagedUniformBuffer(
|
|
4779
|
+
/** Returns the managed uniform buffer for the named block. */
|
|
4780
|
+
getManagedUniformBuffer(uniformBufferName) {
|
|
2957
4781
|
if (!this.uniformBuffers.get(uniformBufferName)) {
|
|
2958
4782
|
const byteLength = this.getUniformBufferByteLength(uniformBufferName);
|
|
2959
|
-
const uniformBuffer = device.createBuffer({
|
|
4783
|
+
const uniformBuffer = this.device.createBuffer({
|
|
2960
4784
|
usage: Buffer2.UNIFORM | Buffer2.COPY_DST,
|
|
2961
4785
|
byteLength
|
|
2962
4786
|
});
|
|
@@ -2964,7 +4788,11 @@ var UniformStore = class {
|
|
|
2964
4788
|
}
|
|
2965
4789
|
return this.uniformBuffers.get(uniformBufferName);
|
|
2966
4790
|
}
|
|
2967
|
-
/**
|
|
4791
|
+
/**
|
|
4792
|
+
* Updates every managed uniform buffer whose source uniforms have changed.
|
|
4793
|
+
*
|
|
4794
|
+
* @returns The first redraw reason encountered, or `false` if nothing changed.
|
|
4795
|
+
*/
|
|
2968
4796
|
updateUniformBuffers() {
|
|
2969
4797
|
let reason = false;
|
|
2970
4798
|
for (const uniformBufferName of this.uniformBlocks.keys()) {
|
|
@@ -2976,7 +4804,11 @@ var UniformStore = class {
|
|
|
2976
4804
|
}
|
|
2977
4805
|
return reason;
|
|
2978
4806
|
}
|
|
2979
|
-
/**
|
|
4807
|
+
/**
|
|
4808
|
+
* Updates one managed uniform buffer if its corresponding block is dirty.
|
|
4809
|
+
*
|
|
4810
|
+
* @returns The redraw reason for the update, or `false` if no write occurred.
|
|
4811
|
+
*/
|
|
2980
4812
|
updateUniformBuffer(uniformBufferName) {
|
|
2981
4813
|
var _a;
|
|
2982
4814
|
const uniformBlock = this.uniformBlocks.get(uniformBufferName);
|
|
@@ -2993,8 +4825,49 @@ var UniformStore = class {
|
|
|
2993
4825
|
return reason;
|
|
2994
4826
|
}
|
|
2995
4827
|
};
|
|
4828
|
+
function getDefaultUniformBufferLayout(device) {
|
|
4829
|
+
return device.type === "webgpu" ? "wgsl-uniform" : "std140";
|
|
4830
|
+
}
|
|
4831
|
+
|
|
4832
|
+
// dist/shadertypes/texture-types/texture-layout.js
|
|
4833
|
+
function getTextureImageView(arrayBuffer2, memoryLayout, format, image = 0) {
|
|
4834
|
+
const formatInfo = textureFormatDecoder.getInfo(format);
|
|
4835
|
+
const bytesPerComponent = formatInfo.bytesPerPixel / formatInfo.components;
|
|
4836
|
+
const { bytesPerImage } = memoryLayout;
|
|
4837
|
+
const offset = bytesPerImage * image;
|
|
4838
|
+
const totalPixels = memoryLayout.bytesPerImage / bytesPerComponent;
|
|
4839
|
+
switch (format) {
|
|
4840
|
+
case "rgba8unorm":
|
|
4841
|
+
case "bgra8unorm":
|
|
4842
|
+
case "rgba8uint":
|
|
4843
|
+
return new Uint8Array(arrayBuffer2, offset, totalPixels);
|
|
4844
|
+
case "r8unorm":
|
|
4845
|
+
return new Uint8Array(arrayBuffer2, offset, totalPixels);
|
|
4846
|
+
case "r16uint":
|
|
4847
|
+
case "rgba16uint":
|
|
4848
|
+
return new Uint16Array(arrayBuffer2, offset, totalPixels);
|
|
4849
|
+
case "r32uint":
|
|
4850
|
+
case "rgba32uint":
|
|
4851
|
+
return new Uint32Array(arrayBuffer2, offset, totalPixels);
|
|
4852
|
+
case "r32float":
|
|
4853
|
+
return new Float32Array(arrayBuffer2, offset, totalPixels);
|
|
4854
|
+
case "rgba16float":
|
|
4855
|
+
return new Uint16Array(arrayBuffer2, offset, totalPixels);
|
|
4856
|
+
case "rgba32float":
|
|
4857
|
+
return new Float32Array(arrayBuffer2, offset, totalPixels);
|
|
4858
|
+
default:
|
|
4859
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
4860
|
+
}
|
|
4861
|
+
}
|
|
4862
|
+
function setTextureImageData(arrayBuffer2, memoryLayout, format, data, image = 0) {
|
|
4863
|
+
const offset = 0;
|
|
4864
|
+
const totalPixels = memoryLayout.bytesPerImage / memoryLayout.bytesPerPixel;
|
|
4865
|
+
const subArray = data.subarray(0, totalPixels);
|
|
4866
|
+
const typedArray = getTextureImageView(arrayBuffer2, memoryLayout, format, image);
|
|
4867
|
+
typedArray.set(subArray, offset);
|
|
4868
|
+
}
|
|
2996
4869
|
|
|
2997
|
-
// dist/shadertypes/
|
|
4870
|
+
// dist/shadertypes/texture-types/pixel-utils.js
|
|
2998
4871
|
function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
2999
4872
|
if (x < 0 || x >= pixelData.width || y < 0 || y >= pixelData.height) {
|
|
3000
4873
|
throw new Error("Coordinates out of bounds.");
|
|
@@ -3004,7 +4877,7 @@ function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
|
3004
4877
|
let bitOffsetWithinPixel = 0;
|
|
3005
4878
|
const channels = [];
|
|
3006
4879
|
for (let i = 0; i < 4; i++) {
|
|
3007
|
-
const bits = bitsPerChannel[i];
|
|
4880
|
+
const bits = bitsPerChannel[i] ?? 0;
|
|
3008
4881
|
if (bits <= 0) {
|
|
3009
4882
|
channels.push(0);
|
|
3010
4883
|
} else {
|
|
@@ -3013,14 +4886,14 @@ function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
|
3013
4886
|
bitOffsetWithinPixel += bits;
|
|
3014
4887
|
}
|
|
3015
4888
|
}
|
|
3016
|
-
return [channels[0], channels[1], channels[2], channels[3]];
|
|
4889
|
+
return [channels[0] ?? 0, channels[1] ?? 0, channels[2] ?? 0, channels[3] ?? 0];
|
|
3017
4890
|
}
|
|
3018
4891
|
function writePixel(dataView, bitOffset, bitsPerChannel, pixel) {
|
|
3019
4892
|
let currentBitOffset = bitOffset;
|
|
3020
4893
|
for (let channel = 0; channel < 4; channel++) {
|
|
3021
|
-
const bits = bitsPerChannel[channel];
|
|
4894
|
+
const bits = bitsPerChannel[channel] ?? 0;
|
|
3022
4895
|
const maxValue = (1 << bits) - 1;
|
|
3023
|
-
const channelValue = pixel[channel] & maxValue;
|
|
4896
|
+
const channelValue = (pixel[channel] ?? 0) & maxValue;
|
|
3024
4897
|
writeBitsToDataView(dataView, currentBitOffset, bits, channelValue);
|
|
3025
4898
|
currentBitOffset += bits;
|
|
3026
4899
|
}
|