@luma.gl/core 9.3.0-alpha.4 → 9.3.0-alpha.8
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 -182
- package/dist/adapter/canvas-context.d.ts.map +1 -1
- package/dist/adapter/canvas-context.js +5 -481
- 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 +76 -11
- package/dist/adapter/device.d.ts.map +1 -1
- package/dist/adapter/device.js +180 -9
- package/dist/adapter/device.js.map +1 -1
- package/dist/adapter/luma.js +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 +1 -1
- package/dist/adapter/resources/buffer.d.ts.map +1 -1
- package/dist/adapter/resources/buffer.js +14 -6
- 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 +25 -2
- 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 +1 -1
- package/dist/adapter/resources/fence.d.ts.map +1 -1
- package/dist/adapter/resources/fence.js +3 -1
- package/dist/adapter/resources/fence.js.map +1 -1
- package/dist/adapter/resources/framebuffer.d.ts +1 -1
- package/dist/adapter/resources/framebuffer.d.ts.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 +8 -0
- package/dist/adapter/resources/resource.d.ts.map +1 -1
- package/dist/adapter/resources/resource.js +240 -14
- package/dist/adapter/resources/resource.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 +82 -15
- package/dist/adapter/resources/texture.d.ts.map +1 -1
- package/dist/adapter/resources/texture.js +186 -33
- 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/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 +1934 -415
- package/dist/dist.min.js +6 -6
- 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 +1858 -409
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +25 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -9
- package/dist/index.js.map +1 -1
- package/dist/portable/uniform-block.d.ts +1 -1
- package/dist/portable/uniform-block.d.ts.map +1 -1
- package/dist/portable/uniform-buffer-layout.d.ts +20 -15
- package/dist/portable/uniform-buffer-layout.d.ts.map +1 -1
- package/dist/portable/uniform-buffer-layout.js +188 -43
- package/dist/portable/uniform-buffer-layout.js.map +1 -1
- package/dist/portable/uniform-store.d.ts +5 -6
- package/dist/portable/uniform-store.d.ts.map +1 -1
- package/dist/portable/uniform-store.js +6 -3
- 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/{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-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/texture-types/pixel-utils.js.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/texture-format-decoder.d.ts +1 -0
- package/dist/shadertypes/texture-types/texture-format-decoder.d.ts.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/texture-format-decoder.js +55 -9
- 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 +10 -3
- 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/{textures → texture-types}/texture-layout.d.ts +1 -1
- package/dist/shadertypes/texture-types/texture-layout.d.ts.map +1 -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/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 +3 -3
- package/src/adapter/canvas-context.ts +7 -623
- package/src/adapter/canvas-observer.ts +130 -0
- package/src/adapter/canvas-surface.ts +521 -0
- package/src/adapter/device.ts +287 -21
- package/src/adapter/presentation-context.ts +16 -0
- package/src/adapter/resources/buffer.ts +13 -5
- package/src/adapter/resources/command-buffer.ts +3 -1
- package/src/adapter/resources/command-encoder.ts +94 -3
- package/src/adapter/resources/compute-pipeline.ts +2 -2
- package/src/adapter/resources/fence.ts +3 -1
- package/src/adapter/resources/framebuffer.ts +1 -1
- package/src/adapter/resources/query-set.ts +17 -1
- package/src/adapter/resources/render-pipeline.ts +52 -16
- package/src/adapter/resources/resource.ts +284 -14
- 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 +273 -43
- 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/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 +54 -26
- package/src/portable/uniform-block.ts +1 -1
- package/src/portable/uniform-buffer-layout.ts +269 -62
- package/src/portable/uniform-store.ts +14 -11
- package/src/shadertypes/data-types/data-type-decoder.ts +105 -0
- package/src/shadertypes/data-types/data-types.ts +100 -48
- package/src/{image-utils → shadertypes/image-types}/image-types.ts +0 -7
- 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}/texture-format-decoder.ts +75 -9
- 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 +20 -3
- 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/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/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 -43
- 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.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/textures/texture-layout.d.ts.map +0 -1
- package/dist/shadertypes/textures/texture-layout.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/shadertypes/data-types/shader-types.ts +0 -94
- 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}/pixel-utils.js +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/{textures → texture-types}/texture-layout.js +0 -0
- /package/dist/shadertypes/{vertex-arrays → vertex-types}/vertex-formats.js +0 -0
- /package/src/shadertypes/{textures → texture-types}/pixel-utils.ts +0 -0
- /package/src/shadertypes/{textures → texture-types}/texture-layout.ts +0 -0
package/dist/index.cjs
CHANGED
|
@@ -38,50 +38,72 @@ __export(dist_exports, {
|
|
|
38
38
|
ExternalTexture: () => ExternalTexture,
|
|
39
39
|
Fence: () => Fence,
|
|
40
40
|
Framebuffer: () => Framebuffer,
|
|
41
|
+
PipelineFactory: () => PipelineFactory,
|
|
41
42
|
PipelineLayout: () => PipelineLayout,
|
|
43
|
+
PresentationContext: () => PresentationContext,
|
|
42
44
|
QuerySet: () => QuerySet,
|
|
43
45
|
RenderPass: () => RenderPass,
|
|
44
46
|
RenderPipeline: () => RenderPipeline,
|
|
45
47
|
Resource: () => Resource,
|
|
46
48
|
Sampler: () => Sampler,
|
|
47
49
|
Shader: () => Shader,
|
|
50
|
+
ShaderFactory: () => ShaderFactory,
|
|
51
|
+
SharedRenderPipeline: () => SharedRenderPipeline,
|
|
48
52
|
Texture: () => Texture,
|
|
49
|
-
TextureFormatDecoder: () => TextureFormatDecoder,
|
|
50
53
|
TextureView: () => TextureView,
|
|
51
54
|
TransformFeedback: () => TransformFeedback,
|
|
52
55
|
UniformBlock: () => UniformBlock,
|
|
53
56
|
UniformBufferLayout: () => UniformBufferLayout,
|
|
54
57
|
UniformStore: () => UniformStore,
|
|
55
58
|
VertexArray: () => VertexArray,
|
|
59
|
+
_getDefaultBindGroupFactory: () => _getDefaultBindGroupFactory,
|
|
56
60
|
_getTextureFormatDefinition: () => getTextureFormatDefinition,
|
|
57
61
|
_getTextureFormatTable: () => getTextureFormatTable,
|
|
58
62
|
assert: () => assert,
|
|
59
63
|
assertDefined: () => assertDefined,
|
|
64
|
+
dataTypeDecoder: () => dataTypeDecoder,
|
|
65
|
+
flattenBindingsByGroup: () => flattenBindingsByGroup,
|
|
60
66
|
getAttributeInfosFromLayouts: () => getAttributeInfosFromLayouts,
|
|
61
67
|
getAttributeShaderTypeInfo: () => getAttributeShaderTypeInfo,
|
|
62
|
-
getDataType: () => getDataType,
|
|
63
|
-
getDataTypeInfo: () => getDataTypeInfo,
|
|
64
68
|
getExternalImageSize: () => getExternalImageSize,
|
|
65
|
-
getNormalizedDataType: () => getNormalizedDataType,
|
|
66
69
|
getScratchArray: () => getScratchArray,
|
|
70
|
+
getShaderLayoutBinding: () => getShaderLayoutBinding,
|
|
67
71
|
getTextureImageView: () => getTextureImageView,
|
|
68
72
|
getTypedArrayConstructor: () => getTypedArrayConstructor,
|
|
69
73
|
getVariableShaderTypeInfo: () => getVariableShaderTypeInfo,
|
|
70
|
-
getVertexFormatFromAttribute: () => getVertexFormatFromAttribute,
|
|
71
|
-
getVertexFormatInfo: () => getVertexFormatInfo,
|
|
72
74
|
isExternalImage: () => isExternalImage,
|
|
73
75
|
log: () => log,
|
|
74
76
|
luma: () => luma,
|
|
75
|
-
|
|
77
|
+
normalizeBindingsByGroup: () => normalizeBindingsByGroup,
|
|
76
78
|
readPixel: () => readPixel,
|
|
77
79
|
setTextureImageData: () => setTextureImageData,
|
|
80
|
+
shaderTypeDecoder: () => shaderTypeDecoder,
|
|
78
81
|
textureFormatDecoder: () => textureFormatDecoder,
|
|
82
|
+
vertexFormatDecoder: () => vertexFormatDecoder,
|
|
79
83
|
writePixel: () => writePixel
|
|
80
84
|
});
|
|
81
85
|
module.exports = __toCommonJS(dist_exports);
|
|
82
86
|
|
|
83
87
|
// dist/utils/stats-manager.js
|
|
84
88
|
var import_stats = require("@probe.gl/stats");
|
|
89
|
+
var GPU_TIME_AND_MEMORY_STATS = "GPU Time and Memory";
|
|
90
|
+
var GPU_TIME_AND_MEMORY_STAT_ORDER = [
|
|
91
|
+
"Adapter",
|
|
92
|
+
"GPU",
|
|
93
|
+
"GPU Type",
|
|
94
|
+
"GPU Backend",
|
|
95
|
+
"Frame Rate",
|
|
96
|
+
"CPU Time",
|
|
97
|
+
"GPU Time",
|
|
98
|
+
"GPU Memory",
|
|
99
|
+
"Buffer Memory",
|
|
100
|
+
"Texture Memory",
|
|
101
|
+
"Referenced Buffer Memory",
|
|
102
|
+
"Referenced Texture Memory",
|
|
103
|
+
"Swap Chain Texture"
|
|
104
|
+
];
|
|
105
|
+
var ORDERED_STATS_CACHE = /* @__PURE__ */ new WeakMap();
|
|
106
|
+
var ORDERED_STAT_NAME_SET_CACHE = /* @__PURE__ */ new WeakMap();
|
|
85
107
|
var StatsManager = class {
|
|
86
108
|
stats = /* @__PURE__ */ new Map();
|
|
87
109
|
getStats(name2) {
|
|
@@ -91,10 +113,50 @@ var StatsManager = class {
|
|
|
91
113
|
if (!this.stats.has(name2)) {
|
|
92
114
|
this.stats.set(name2, new import_stats.Stats({ id: name2 }));
|
|
93
115
|
}
|
|
94
|
-
|
|
116
|
+
const stats = this.stats.get(name2);
|
|
117
|
+
if (name2 === GPU_TIME_AND_MEMORY_STATS) {
|
|
118
|
+
initializeStats(stats, GPU_TIME_AND_MEMORY_STAT_ORDER);
|
|
119
|
+
}
|
|
120
|
+
return stats;
|
|
95
121
|
}
|
|
96
122
|
};
|
|
97
123
|
var lumaStats = new StatsManager();
|
|
124
|
+
function initializeStats(stats, orderedStatNames) {
|
|
125
|
+
const statsMap = stats.stats;
|
|
126
|
+
let addedOrderedStat = false;
|
|
127
|
+
for (const statName of orderedStatNames) {
|
|
128
|
+
if (!statsMap[statName]) {
|
|
129
|
+
stats.get(statName);
|
|
130
|
+
addedOrderedStat = true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const statCount = Object.keys(statsMap).length;
|
|
134
|
+
const cachedStats = ORDERED_STATS_CACHE.get(stats);
|
|
135
|
+
if (!addedOrderedStat && (cachedStats == null ? void 0 : cachedStats.orderedStatNames) === orderedStatNames && cachedStats.statCount === statCount) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const reorderedStats = {};
|
|
139
|
+
let orderedStatNamesSet = ORDERED_STAT_NAME_SET_CACHE.get(orderedStatNames);
|
|
140
|
+
if (!orderedStatNamesSet) {
|
|
141
|
+
orderedStatNamesSet = new Set(orderedStatNames);
|
|
142
|
+
ORDERED_STAT_NAME_SET_CACHE.set(orderedStatNames, orderedStatNamesSet);
|
|
143
|
+
}
|
|
144
|
+
for (const statName of orderedStatNames) {
|
|
145
|
+
if (statsMap[statName]) {
|
|
146
|
+
reorderedStats[statName] = statsMap[statName];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
for (const [statName, stat] of Object.entries(statsMap)) {
|
|
150
|
+
if (!orderedStatNamesSet.has(statName)) {
|
|
151
|
+
reorderedStats[statName] = stat;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
for (const statName of Object.keys(statsMap)) {
|
|
155
|
+
delete statsMap[statName];
|
|
156
|
+
}
|
|
157
|
+
Object.assign(statsMap, reorderedStats);
|
|
158
|
+
ORDERED_STATS_CACHE.set(stats, { orderedStatNames, statCount });
|
|
159
|
+
}
|
|
98
160
|
|
|
99
161
|
// dist/utils/log.js
|
|
100
162
|
var import_log = require("@probe.gl/log");
|
|
@@ -109,6 +171,57 @@ function uid(id = "id") {
|
|
|
109
171
|
}
|
|
110
172
|
|
|
111
173
|
// dist/adapter/resources/resource.js
|
|
174
|
+
var CPU_HOTSPOT_PROFILER_MODULE = "cpu-hotspot-profiler";
|
|
175
|
+
var RESOURCE_COUNTS_STATS = "GPU Resource Counts";
|
|
176
|
+
var LEGACY_RESOURCE_COUNTS_STATS = "Resource Counts";
|
|
177
|
+
var GPU_TIME_AND_MEMORY_STATS2 = "GPU Time and Memory";
|
|
178
|
+
var BASE_RESOURCE_COUNT_ORDER = [
|
|
179
|
+
"Resources",
|
|
180
|
+
"Buffers",
|
|
181
|
+
"Textures",
|
|
182
|
+
"Samplers",
|
|
183
|
+
"TextureViews",
|
|
184
|
+
"Framebuffers",
|
|
185
|
+
"QuerySets",
|
|
186
|
+
"Shaders",
|
|
187
|
+
"RenderPipelines",
|
|
188
|
+
"ComputePipelines",
|
|
189
|
+
"PipelineLayouts",
|
|
190
|
+
"VertexArrays",
|
|
191
|
+
"RenderPasss",
|
|
192
|
+
"ComputePasss",
|
|
193
|
+
"CommandEncoders",
|
|
194
|
+
"CommandBuffers"
|
|
195
|
+
];
|
|
196
|
+
var WEBGL_RESOURCE_COUNT_ORDER = [
|
|
197
|
+
"Resources",
|
|
198
|
+
"Buffers",
|
|
199
|
+
"Textures",
|
|
200
|
+
"Samplers",
|
|
201
|
+
"TextureViews",
|
|
202
|
+
"Framebuffers",
|
|
203
|
+
"QuerySets",
|
|
204
|
+
"Shaders",
|
|
205
|
+
"RenderPipelines",
|
|
206
|
+
"SharedRenderPipelines",
|
|
207
|
+
"ComputePipelines",
|
|
208
|
+
"PipelineLayouts",
|
|
209
|
+
"VertexArrays",
|
|
210
|
+
"RenderPasss",
|
|
211
|
+
"ComputePasss",
|
|
212
|
+
"CommandEncoders",
|
|
213
|
+
"CommandBuffers"
|
|
214
|
+
];
|
|
215
|
+
var BASE_RESOURCE_COUNT_STAT_ORDER = BASE_RESOURCE_COUNT_ORDER.flatMap((resourceType) => [
|
|
216
|
+
`${resourceType} Created`,
|
|
217
|
+
`${resourceType} Active`
|
|
218
|
+
]);
|
|
219
|
+
var WEBGL_RESOURCE_COUNT_STAT_ORDER = WEBGL_RESOURCE_COUNT_ORDER.flatMap((resourceType) => [
|
|
220
|
+
`${resourceType} Created`,
|
|
221
|
+
`${resourceType} Active`
|
|
222
|
+
]);
|
|
223
|
+
var ORDERED_STATS_CACHE2 = /* @__PURE__ */ new WeakMap();
|
|
224
|
+
var ORDERED_STAT_NAME_SET_CACHE2 = /* @__PURE__ */ new WeakMap();
|
|
112
225
|
var Resource = class {
|
|
113
226
|
toString() {
|
|
114
227
|
return `${this[Symbol.toStringTag] || this.constructor.name}:"${this.id}"`;
|
|
@@ -125,6 +238,8 @@ var Resource = class {
|
|
|
125
238
|
destroyed = false;
|
|
126
239
|
/** For resources that allocate GPU memory */
|
|
127
240
|
allocatedBytes = 0;
|
|
241
|
+
/** Stats bucket currently holding the tracked allocation */
|
|
242
|
+
allocatedBytesName = null;
|
|
128
243
|
/** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
|
|
129
244
|
_attachedResources = /* @__PURE__ */ new Set();
|
|
130
245
|
/**
|
|
@@ -146,6 +261,9 @@ var Resource = class {
|
|
|
146
261
|
* destroy can be called on any resource to release it before it is garbage collected.
|
|
147
262
|
*/
|
|
148
263
|
destroy() {
|
|
264
|
+
if (this.destroyed) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
149
267
|
this.destroyResource();
|
|
150
268
|
}
|
|
151
269
|
/** @deprecated Use destroy() */
|
|
@@ -184,7 +302,7 @@ var Resource = class {
|
|
|
184
302
|
}
|
|
185
303
|
/** Destroy all owned resources. Make sure the resources are no longer needed before calling. */
|
|
186
304
|
destroyAttachedResources() {
|
|
187
|
-
for (const resource of
|
|
305
|
+
for (const resource of this._attachedResources) {
|
|
188
306
|
resource.destroy();
|
|
189
307
|
}
|
|
190
308
|
this._attachedResources = /* @__PURE__ */ new Set();
|
|
@@ -192,37 +310,107 @@ var Resource = class {
|
|
|
192
310
|
// PROTECTED METHODS
|
|
193
311
|
/** Perform all destroy steps. Can be called by derived resources when overriding destroy() */
|
|
194
312
|
destroyResource() {
|
|
313
|
+
if (this.destroyed) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
195
316
|
this.destroyAttachedResources();
|
|
196
317
|
this.removeStats();
|
|
197
318
|
this.destroyed = true;
|
|
198
319
|
}
|
|
199
320
|
/** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
|
|
200
321
|
removeStats() {
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
|
|
322
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
323
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
324
|
+
const statsObjects = [
|
|
325
|
+
this._device.statsManager.getStats(RESOURCE_COUNTS_STATS),
|
|
326
|
+
this._device.statsManager.getStats(LEGACY_RESOURCE_COUNTS_STATS)
|
|
327
|
+
];
|
|
328
|
+
const orderedStatNames = getResourceCountStatOrder(this._device);
|
|
329
|
+
for (const stats of statsObjects) {
|
|
330
|
+
initializeStats2(stats, orderedStatNames);
|
|
331
|
+
}
|
|
332
|
+
const name2 = this.getStatsName();
|
|
333
|
+
for (const stats of statsObjects) {
|
|
334
|
+
stats.get("Resources Active").decrementCount();
|
|
335
|
+
stats.get(`${name2}s Active`).decrementCount();
|
|
336
|
+
}
|
|
337
|
+
if (profiler) {
|
|
338
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
339
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
340
|
+
}
|
|
204
341
|
}
|
|
205
342
|
/** Called by subclass to track memory allocations */
|
|
206
|
-
trackAllocatedMemory(bytes, name2 = this
|
|
207
|
-
const
|
|
343
|
+
trackAllocatedMemory(bytes, name2 = this.getStatsName()) {
|
|
344
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
345
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
346
|
+
const stats = this._device.statsManager.getStats(GPU_TIME_AND_MEMORY_STATS2);
|
|
347
|
+
if (this.allocatedBytes > 0 && this.allocatedBytesName) {
|
|
348
|
+
stats.get("GPU Memory").subtractCount(this.allocatedBytes);
|
|
349
|
+
stats.get(`${this.allocatedBytesName} Memory`).subtractCount(this.allocatedBytes);
|
|
350
|
+
}
|
|
208
351
|
stats.get("GPU Memory").addCount(bytes);
|
|
209
352
|
stats.get(`${name2} Memory`).addCount(bytes);
|
|
353
|
+
if (profiler) {
|
|
354
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
355
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
356
|
+
}
|
|
210
357
|
this.allocatedBytes = bytes;
|
|
358
|
+
this.allocatedBytesName = name2;
|
|
359
|
+
}
|
|
360
|
+
/** Called by subclass to track handle-backed memory allocations separately from owned allocations */
|
|
361
|
+
trackReferencedMemory(bytes, name2 = this.getStatsName()) {
|
|
362
|
+
this.trackAllocatedMemory(bytes, `Referenced ${name2}`);
|
|
211
363
|
}
|
|
212
364
|
/** Called by subclass to track memory deallocations */
|
|
213
|
-
trackDeallocatedMemory(name2 = this
|
|
214
|
-
|
|
365
|
+
trackDeallocatedMemory(name2 = this.getStatsName()) {
|
|
366
|
+
if (this.allocatedBytes === 0) {
|
|
367
|
+
this.allocatedBytesName = null;
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
371
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
372
|
+
const stats = this._device.statsManager.getStats(GPU_TIME_AND_MEMORY_STATS2);
|
|
215
373
|
stats.get("GPU Memory").subtractCount(this.allocatedBytes);
|
|
216
|
-
stats.get(`${name2} Memory`).subtractCount(this.allocatedBytes);
|
|
374
|
+
stats.get(`${this.allocatedBytesName || name2} Memory`).subtractCount(this.allocatedBytes);
|
|
375
|
+
if (profiler) {
|
|
376
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
377
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
378
|
+
}
|
|
217
379
|
this.allocatedBytes = 0;
|
|
380
|
+
this.allocatedBytesName = null;
|
|
381
|
+
}
|
|
382
|
+
/** Called by subclass to deallocate handle-backed memory tracked via trackReferencedMemory() */
|
|
383
|
+
trackDeallocatedReferencedMemory(name2 = this.getStatsName()) {
|
|
384
|
+
this.trackDeallocatedMemory(`Referenced ${name2}`);
|
|
218
385
|
}
|
|
219
386
|
/** Called by resource constructor to track object creation */
|
|
220
387
|
addStats() {
|
|
221
|
-
const
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
388
|
+
const name2 = this.getStatsName();
|
|
389
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
390
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
391
|
+
const statsObjects = [
|
|
392
|
+
this._device.statsManager.getStats(RESOURCE_COUNTS_STATS),
|
|
393
|
+
this._device.statsManager.getStats(LEGACY_RESOURCE_COUNTS_STATS)
|
|
394
|
+
];
|
|
395
|
+
const orderedStatNames = getResourceCountStatOrder(this._device);
|
|
396
|
+
for (const stats of statsObjects) {
|
|
397
|
+
initializeStats2(stats, orderedStatNames);
|
|
398
|
+
}
|
|
399
|
+
for (const stats of statsObjects) {
|
|
400
|
+
stats.get("Resources Created").incrementCount();
|
|
401
|
+
stats.get("Resources Active").incrementCount();
|
|
402
|
+
stats.get(`${name2}s Created`).incrementCount();
|
|
403
|
+
stats.get(`${name2}s Active`).incrementCount();
|
|
404
|
+
}
|
|
405
|
+
if (profiler) {
|
|
406
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
407
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
408
|
+
}
|
|
409
|
+
recordTransientCanvasResourceCreate(this._device, name2);
|
|
410
|
+
}
|
|
411
|
+
/** Canonical resource name used for stats buckets. */
|
|
412
|
+
getStatsName() {
|
|
413
|
+
return getCanonicalResourceName(this);
|
|
226
414
|
}
|
|
227
415
|
};
|
|
228
416
|
/** Default properties for resource */
|
|
@@ -240,6 +428,97 @@ function selectivelyMerge(props, defaultProps) {
|
|
|
240
428
|
}
|
|
241
429
|
return mergedProps;
|
|
242
430
|
}
|
|
431
|
+
function initializeStats2(stats, orderedStatNames) {
|
|
432
|
+
const statsMap = stats.stats;
|
|
433
|
+
let addedOrderedStat = false;
|
|
434
|
+
for (const statName of orderedStatNames) {
|
|
435
|
+
if (!statsMap[statName]) {
|
|
436
|
+
stats.get(statName);
|
|
437
|
+
addedOrderedStat = true;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const statCount = Object.keys(statsMap).length;
|
|
441
|
+
const cachedStats = ORDERED_STATS_CACHE2.get(stats);
|
|
442
|
+
if (!addedOrderedStat && (cachedStats == null ? void 0 : cachedStats.orderedStatNames) === orderedStatNames && cachedStats.statCount === statCount) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
const reorderedStats = {};
|
|
446
|
+
let orderedStatNamesSet = ORDERED_STAT_NAME_SET_CACHE2.get(orderedStatNames);
|
|
447
|
+
if (!orderedStatNamesSet) {
|
|
448
|
+
orderedStatNamesSet = new Set(orderedStatNames);
|
|
449
|
+
ORDERED_STAT_NAME_SET_CACHE2.set(orderedStatNames, orderedStatNamesSet);
|
|
450
|
+
}
|
|
451
|
+
for (const statName of orderedStatNames) {
|
|
452
|
+
if (statsMap[statName]) {
|
|
453
|
+
reorderedStats[statName] = statsMap[statName];
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
for (const [statName, stat] of Object.entries(statsMap)) {
|
|
457
|
+
if (!orderedStatNamesSet.has(statName)) {
|
|
458
|
+
reorderedStats[statName] = stat;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
for (const statName of Object.keys(statsMap)) {
|
|
462
|
+
delete statsMap[statName];
|
|
463
|
+
}
|
|
464
|
+
Object.assign(statsMap, reorderedStats);
|
|
465
|
+
ORDERED_STATS_CACHE2.set(stats, { orderedStatNames, statCount });
|
|
466
|
+
}
|
|
467
|
+
function getResourceCountStatOrder(device) {
|
|
468
|
+
return device.type === "webgl" ? WEBGL_RESOURCE_COUNT_STAT_ORDER : BASE_RESOURCE_COUNT_STAT_ORDER;
|
|
469
|
+
}
|
|
470
|
+
function getCpuHotspotProfiler(device) {
|
|
471
|
+
const profiler = device.userData[CPU_HOTSPOT_PROFILER_MODULE];
|
|
472
|
+
return (profiler == null ? void 0 : profiler.enabled) ? profiler : null;
|
|
473
|
+
}
|
|
474
|
+
function getTimestamp() {
|
|
475
|
+
var _a, _b;
|
|
476
|
+
return ((_b = (_a = globalThis.performance) == null ? void 0 : _a.now) == null ? void 0 : _b.call(_a)) ?? Date.now();
|
|
477
|
+
}
|
|
478
|
+
function recordTransientCanvasResourceCreate(device, name2) {
|
|
479
|
+
const profiler = getCpuHotspotProfiler(device);
|
|
480
|
+
if (!profiler || !profiler.activeDefaultFramebufferAcquireDepth) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
profiler.transientCanvasResourceCreates = (profiler.transientCanvasResourceCreates || 0) + 1;
|
|
484
|
+
switch (name2) {
|
|
485
|
+
case "Texture":
|
|
486
|
+
profiler.transientCanvasTextureCreates = (profiler.transientCanvasTextureCreates || 0) + 1;
|
|
487
|
+
break;
|
|
488
|
+
case "TextureView":
|
|
489
|
+
profiler.transientCanvasTextureViewCreates = (profiler.transientCanvasTextureViewCreates || 0) + 1;
|
|
490
|
+
break;
|
|
491
|
+
case "Sampler":
|
|
492
|
+
profiler.transientCanvasSamplerCreates = (profiler.transientCanvasSamplerCreates || 0) + 1;
|
|
493
|
+
break;
|
|
494
|
+
case "Framebuffer":
|
|
495
|
+
profiler.transientCanvasFramebufferCreates = (profiler.transientCanvasFramebufferCreates || 0) + 1;
|
|
496
|
+
break;
|
|
497
|
+
default:
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
function getCanonicalResourceName(resource) {
|
|
502
|
+
let prototype = Object.getPrototypeOf(resource);
|
|
503
|
+
while (prototype) {
|
|
504
|
+
const parentPrototype = Object.getPrototypeOf(prototype);
|
|
505
|
+
if (!parentPrototype || parentPrototype === Resource.prototype) {
|
|
506
|
+
return getPrototypeToStringTag(prototype) || resource[Symbol.toStringTag] || resource.constructor.name;
|
|
507
|
+
}
|
|
508
|
+
prototype = parentPrototype;
|
|
509
|
+
}
|
|
510
|
+
return resource[Symbol.toStringTag] || resource.constructor.name;
|
|
511
|
+
}
|
|
512
|
+
function getPrototypeToStringTag(prototype) {
|
|
513
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, Symbol.toStringTag);
|
|
514
|
+
if (typeof (descriptor == null ? void 0 : descriptor.get) === "function") {
|
|
515
|
+
return descriptor.get.call(prototype);
|
|
516
|
+
}
|
|
517
|
+
if (typeof (descriptor == null ? void 0 : descriptor.value) === "string") {
|
|
518
|
+
return descriptor.value;
|
|
519
|
+
}
|
|
520
|
+
return null;
|
|
521
|
+
}
|
|
243
522
|
|
|
244
523
|
// dist/adapter/resources/buffer.js
|
|
245
524
|
var _Buffer = class extends Resource {
|
|
@@ -279,15 +558,23 @@ var _Buffer = class extends Resource {
|
|
|
279
558
|
/** A partial CPU-side copy of the data in this buffer, for debugging purposes */
|
|
280
559
|
debugData = new ArrayBuffer(0);
|
|
281
560
|
/** This doesn't handle partial non-zero offset updates correctly */
|
|
282
|
-
_setDebugData(data,
|
|
283
|
-
|
|
561
|
+
_setDebugData(data, _byteOffset, byteLength) {
|
|
562
|
+
let arrayBufferView = null;
|
|
563
|
+
let arrayBuffer2;
|
|
564
|
+
if (ArrayBuffer.isView(data)) {
|
|
565
|
+
arrayBufferView = data;
|
|
566
|
+
arrayBuffer2 = data.buffer;
|
|
567
|
+
} else {
|
|
568
|
+
arrayBuffer2 = data;
|
|
569
|
+
}
|
|
284
570
|
const debugDataLength = Math.min(data ? data.byteLength : byteLength, _Buffer.DEBUG_DATA_MAX_LENGTH);
|
|
285
571
|
if (arrayBuffer2 === null) {
|
|
286
572
|
this.debugData = new ArrayBuffer(debugDataLength);
|
|
287
|
-
} else if (byteOffset === 0 && byteLength === arrayBuffer2.byteLength) {
|
|
288
|
-
this.debugData = arrayBuffer2.slice(0, debugDataLength);
|
|
289
573
|
} else {
|
|
290
|
-
|
|
574
|
+
const sourceByteOffset = Math.min((arrayBufferView == null ? void 0 : arrayBufferView.byteOffset) || 0, arrayBuffer2.byteLength);
|
|
575
|
+
const availableByteLength = Math.max(0, arrayBuffer2.byteLength - sourceByteOffset);
|
|
576
|
+
const copyByteLength = Math.min(debugDataLength, availableByteLength);
|
|
577
|
+
this.debugData = new Uint8Array(arrayBuffer2, sourceByteOffset, copyByteLength).slice().buffer;
|
|
291
578
|
}
|
|
292
579
|
}
|
|
293
580
|
};
|
|
@@ -321,62 +608,73 @@ __publicField(Buffer2, "defaultProps", {
|
|
|
321
608
|
onMapped: void 0
|
|
322
609
|
});
|
|
323
610
|
|
|
324
|
-
// dist/shadertypes/data-types/
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
return "unorm8";
|
|
345
|
-
case "sint8":
|
|
346
|
-
return "snorm8";
|
|
347
|
-
case "uint16":
|
|
348
|
-
return "unorm16";
|
|
349
|
-
case "sint16":
|
|
350
|
-
return "snorm16";
|
|
351
|
-
default:
|
|
352
|
-
return dataType;
|
|
611
|
+
// dist/shadertypes/data-types/data-type-decoder.js
|
|
612
|
+
var DataTypeDecoder = class {
|
|
613
|
+
/**
|
|
614
|
+
* Gets info about a data type constant (signed or normalized)
|
|
615
|
+
* @returns underlying primitive / signed types, byte length, normalization, integer, signed flags
|
|
616
|
+
*/
|
|
617
|
+
getDataTypeInfo(type) {
|
|
618
|
+
const [signedType, primitiveType, byteLength] = NORMALIZED_TYPE_MAP[type];
|
|
619
|
+
const normalized = type.includes("norm");
|
|
620
|
+
const integer = !normalized && !type.startsWith("float");
|
|
621
|
+
const signed = type.startsWith("s");
|
|
622
|
+
return {
|
|
623
|
+
signedType,
|
|
624
|
+
primitiveType,
|
|
625
|
+
byteLength,
|
|
626
|
+
normalized,
|
|
627
|
+
integer,
|
|
628
|
+
signed
|
|
629
|
+
// TODO - add webglOnly flag
|
|
630
|
+
};
|
|
353
631
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
632
|
+
/** Build a vertex format from a signed data type and a component */
|
|
633
|
+
getNormalizedDataType(signedDataType) {
|
|
634
|
+
const dataType = signedDataType;
|
|
635
|
+
switch (dataType) {
|
|
636
|
+
case "uint8":
|
|
637
|
+
return "unorm8";
|
|
638
|
+
case "sint8":
|
|
639
|
+
return "snorm8";
|
|
640
|
+
case "uint16":
|
|
641
|
+
return "unorm16";
|
|
642
|
+
case "sint16":
|
|
643
|
+
return "snorm16";
|
|
644
|
+
default:
|
|
645
|
+
return dataType;
|
|
646
|
+
}
|
|
363
647
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
648
|
+
/** Align offset to 1, 2 or 4 elements (4, 8 or 16 bytes) */
|
|
649
|
+
alignTo(size, count) {
|
|
650
|
+
switch (count) {
|
|
651
|
+
case 1:
|
|
652
|
+
return size;
|
|
653
|
+
case 2:
|
|
654
|
+
return size + size % 2;
|
|
655
|
+
default:
|
|
656
|
+
return size + (4 - size % 4) % 4;
|
|
657
|
+
}
|
|
369
658
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
659
|
+
/** Returns the VariableShaderType that corresponds to a typed array */
|
|
660
|
+
getDataType(arrayOrType) {
|
|
661
|
+
const Constructor = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType;
|
|
662
|
+
if (Constructor === Uint8ClampedArray) {
|
|
663
|
+
return "uint8";
|
|
664
|
+
}
|
|
665
|
+
const info = Object.values(NORMALIZED_TYPE_MAP).find((entry) => Constructor === entry[4]);
|
|
666
|
+
if (!info) {
|
|
667
|
+
throw new Error(Constructor.name);
|
|
668
|
+
}
|
|
669
|
+
return info[0];
|
|
373
670
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
671
|
+
/** Returns the TypedArray that corresponds to a shader data type */
|
|
672
|
+
getTypedArrayConstructor(type) {
|
|
673
|
+
const [, , , , Constructor] = NORMALIZED_TYPE_MAP[type];
|
|
674
|
+
return Constructor;
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
var dataTypeDecoder = new DataTypeDecoder();
|
|
380
678
|
var NORMALIZED_TYPE_MAP = {
|
|
381
679
|
uint8: ["uint8", "u32", 1, false, Uint8Array],
|
|
382
680
|
sint8: ["sint8", "i32", 1, false, Int8Array],
|
|
@@ -392,87 +690,99 @@ var NORMALIZED_TYPE_MAP = {
|
|
|
392
690
|
sint32: ["sint32", "i32", 4, false, Int32Array]
|
|
393
691
|
};
|
|
394
692
|
|
|
395
|
-
// dist/shadertypes/vertex-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
type
|
|
408
|
-
components
|
|
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
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
693
|
+
// dist/shadertypes/vertex-types/vertex-format-decoder.js
|
|
694
|
+
var VertexFormatDecoder = class {
|
|
695
|
+
/**
|
|
696
|
+
* Decodes a vertex format, returning type, components, byte length and flags (integer, signed, normalized)
|
|
697
|
+
*/
|
|
698
|
+
getVertexFormatInfo(format) {
|
|
699
|
+
let webglOnly;
|
|
700
|
+
if (format.endsWith("-webgl")) {
|
|
701
|
+
format.replace("-webgl", "");
|
|
702
|
+
webglOnly = true;
|
|
703
|
+
}
|
|
704
|
+
const [type_, count] = format.split("x");
|
|
705
|
+
const type = type_;
|
|
706
|
+
const components = count ? parseInt(count) : 1;
|
|
707
|
+
const decodedType = dataTypeDecoder.getDataTypeInfo(type);
|
|
708
|
+
const result = {
|
|
709
|
+
type,
|
|
710
|
+
components,
|
|
711
|
+
byteLength: decodedType.byteLength * components,
|
|
712
|
+
integer: decodedType.integer,
|
|
713
|
+
signed: decodedType.signed,
|
|
714
|
+
normalized: decodedType.normalized
|
|
715
|
+
};
|
|
716
|
+
if (webglOnly) {
|
|
717
|
+
result.webglOnly = true;
|
|
718
|
+
}
|
|
719
|
+
return result;
|
|
720
|
+
}
|
|
721
|
+
/** Build a vertex format from a signed data type and a component */
|
|
722
|
+
makeVertexFormat(signedDataType, components, normalized) {
|
|
723
|
+
const dataType = normalized ? dataTypeDecoder.getNormalizedDataType(signedDataType) : signedDataType;
|
|
724
|
+
switch (dataType) {
|
|
725
|
+
case "unorm8":
|
|
726
|
+
if (components === 1) {
|
|
727
|
+
return "unorm8";
|
|
728
|
+
}
|
|
729
|
+
if (components === 3) {
|
|
730
|
+
return "unorm8x3-webgl";
|
|
731
|
+
}
|
|
732
|
+
return `${dataType}x${components}`;
|
|
733
|
+
case "snorm8":
|
|
734
|
+
case "uint8":
|
|
735
|
+
case "sint8":
|
|
736
|
+
case "uint16":
|
|
737
|
+
case "sint16":
|
|
738
|
+
case "unorm16":
|
|
739
|
+
case "snorm16":
|
|
740
|
+
case "float16":
|
|
741
|
+
if (components === 1 || components === 3) {
|
|
742
|
+
throw new Error(`size: ${components}`);
|
|
743
|
+
}
|
|
744
|
+
return `${dataType}x${components}`;
|
|
745
|
+
default:
|
|
746
|
+
return components === 1 ? dataType : `${dataType}x${components}`;
|
|
747
|
+
}
|
|
449
748
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
vertexType = "float32";
|
|
459
|
-
break;
|
|
460
|
-
case "i32":
|
|
461
|
-
vertexType = "sint32";
|
|
462
|
-
break;
|
|
463
|
-
case "u32":
|
|
464
|
-
vertexType = "uint32";
|
|
465
|
-
break;
|
|
466
|
-
case "f16":
|
|
467
|
-
return opts.components <= 2 ? "float16x2" : "float16x4";
|
|
749
|
+
/** Get the vertex format for an attribute with TypedArray and size */
|
|
750
|
+
getVertexFormatFromAttribute(typedArray, size, normalized) {
|
|
751
|
+
if (!size || size > 4) {
|
|
752
|
+
throw new Error(`size ${size}`);
|
|
753
|
+
}
|
|
754
|
+
const components = size;
|
|
755
|
+
const signedDataType = dataTypeDecoder.getDataType(typedArray);
|
|
756
|
+
return this.makeVertexFormat(signedDataType, components, normalized);
|
|
468
757
|
}
|
|
469
|
-
|
|
470
|
-
|
|
758
|
+
/**
|
|
759
|
+
* Return a "default" vertex format for a certain shader data type
|
|
760
|
+
* The simplest vertex format that matches the shader attribute's data type
|
|
761
|
+
*/
|
|
762
|
+
getCompatibleVertexFormat(opts) {
|
|
763
|
+
let vertexType;
|
|
764
|
+
switch (opts.primitiveType) {
|
|
765
|
+
case "f32":
|
|
766
|
+
vertexType = "float32";
|
|
767
|
+
break;
|
|
768
|
+
case "i32":
|
|
769
|
+
vertexType = "sint32";
|
|
770
|
+
break;
|
|
771
|
+
case "u32":
|
|
772
|
+
vertexType = "uint32";
|
|
773
|
+
break;
|
|
774
|
+
case "f16":
|
|
775
|
+
return opts.components <= 2 ? "float16x2" : "float16x4";
|
|
776
|
+
}
|
|
777
|
+
if (opts.components === 1) {
|
|
778
|
+
return vertexType;
|
|
779
|
+
}
|
|
780
|
+
return `${vertexType}x${opts.components}`;
|
|
471
781
|
}
|
|
472
|
-
|
|
473
|
-
|
|
782
|
+
};
|
|
783
|
+
var vertexFormatDecoder = new VertexFormatDecoder();
|
|
474
784
|
|
|
475
|
-
// dist/shadertypes/
|
|
785
|
+
// dist/shadertypes/texture-types/texture-format-table.js
|
|
476
786
|
var texture_compression_bc = "texture-compression-bc";
|
|
477
787
|
var texture_compression_astc = "texture-compression-astc";
|
|
478
788
|
var texture_compression_etc2 = "texture-compression-etc2";
|
|
@@ -483,6 +793,7 @@ var float32_renderable = "float32-renderable-webgl";
|
|
|
483
793
|
var float16_renderable = "float16-renderable-webgl";
|
|
484
794
|
var rgb9e5ufloat_renderable = "rgb9e5ufloat-renderable-webgl";
|
|
485
795
|
var snorm8_renderable = "snorm8-renderable-webgl";
|
|
796
|
+
var norm16_webgl = "norm16-webgl";
|
|
486
797
|
var norm16_renderable = "norm16-renderable-webgl";
|
|
487
798
|
var snorm16_renderable = "snorm16-renderable-webgl";
|
|
488
799
|
var float32_filterable = "float32-filterable";
|
|
@@ -516,16 +827,16 @@ var TEXTURE_FORMAT_COLOR_DEPTH_TABLE = {
|
|
|
516
827
|
"rgba8sint": {},
|
|
517
828
|
"bgra8unorm": {},
|
|
518
829
|
"bgra8unorm-srgb": {},
|
|
519
|
-
"r16unorm": { f: norm16_renderable },
|
|
520
|
-
"rg16unorm": { render: norm16_renderable },
|
|
521
|
-
"rgb16unorm-webgl": { f:
|
|
830
|
+
"r16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
831
|
+
"rg16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
832
|
+
"rgb16unorm-webgl": { f: norm16_webgl, render: false },
|
|
522
833
|
// rgb not renderable
|
|
523
|
-
"rgba16unorm": { render: norm16_renderable },
|
|
524
|
-
"r16snorm": { f: snorm16_renderable },
|
|
525
|
-
"rg16snorm": { render: snorm16_renderable },
|
|
526
|
-
"rgb16snorm-webgl": { f:
|
|
834
|
+
"rgba16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
835
|
+
"r16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
836
|
+
"rg16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
837
|
+
"rgb16snorm-webgl": { f: norm16_webgl, render: false },
|
|
527
838
|
// rgb not renderable
|
|
528
|
-
"rgba16snorm": { render: snorm16_renderable },
|
|
839
|
+
"rgba16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
529
840
|
"r16uint": {},
|
|
530
841
|
"rg16uint": {},
|
|
531
842
|
"rgba16uint": {},
|
|
@@ -628,7 +939,7 @@ var TEXTURE_FORMAT_COMPRESSED_TABLE = {
|
|
|
628
939
|
// WEBGL_compressed_texture_pvrtc
|
|
629
940
|
"pvrtc-rgb4unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
630
941
|
"pvrtc-rgba4unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
631
|
-
"pvrtc-
|
|
942
|
+
"pvrtc-rgb2unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
632
943
|
"pvrtc-rgba2unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
633
944
|
// WEBGL_compressed_texture_etc1
|
|
634
945
|
"etc1-rbg-unorm-webgl": { f: texture_compression_etc1_webgl },
|
|
@@ -642,7 +953,7 @@ var TEXTURE_FORMAT_TABLE = {
|
|
|
642
953
|
...TEXTURE_FORMAT_COMPRESSED_TABLE
|
|
643
954
|
};
|
|
644
955
|
|
|
645
|
-
// dist/shadertypes/
|
|
956
|
+
// dist/shadertypes/texture-types/texture-format-decoder.js
|
|
646
957
|
var RGB_FORMAT_REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
|
|
647
958
|
var COLOR_FORMAT_PREFIXES = ["rgb", "rgba", "bgra"];
|
|
648
959
|
var DEPTH_FORMAT_PREFIXES = ["depth", "stencil"];
|
|
@@ -689,10 +1000,13 @@ var TextureFormatDecoder = class {
|
|
|
689
1000
|
};
|
|
690
1001
|
var textureFormatDecoder = new TextureFormatDecoder();
|
|
691
1002
|
function computeTextureMemoryLayout({ format, width, height, depth, byteAlignment }) {
|
|
692
|
-
const
|
|
693
|
-
const
|
|
1003
|
+
const formatInfo = textureFormatDecoder.getInfo(format);
|
|
1004
|
+
const { bytesPerPixel, bytesPerBlock = bytesPerPixel, blockWidth = 1, blockHeight = 1, compressed = false } = formatInfo;
|
|
1005
|
+
const blockColumns = compressed ? Math.ceil(width / blockWidth) : width;
|
|
1006
|
+
const blockRows = compressed ? Math.ceil(height / blockHeight) : height;
|
|
1007
|
+
const unpaddedBytesPerRow = blockColumns * bytesPerBlock;
|
|
694
1008
|
const bytesPerRow = Math.ceil(unpaddedBytesPerRow / byteAlignment) * byteAlignment;
|
|
695
|
-
const rowsPerImage =
|
|
1009
|
+
const rowsPerImage = blockRows;
|
|
696
1010
|
const byteLength = bytesPerRow * rowsPerImage * depth;
|
|
697
1011
|
return {
|
|
698
1012
|
bytesPerPixel,
|
|
@@ -718,7 +1032,8 @@ function getTextureFormatCapabilities(format) {
|
|
|
718
1032
|
const isSigned = formatInfo == null ? void 0 : formatInfo.signed;
|
|
719
1033
|
const isInteger = formatInfo == null ? void 0 : formatInfo.integer;
|
|
720
1034
|
const isWebGLSpecific = formatInfo == null ? void 0 : formatInfo.webgl;
|
|
721
|
-
|
|
1035
|
+
const isCompressed = Boolean(formatInfo == null ? void 0 : formatInfo.compressed);
|
|
1036
|
+
formatCapabilities.render &&= !isDepthStencil && !isCompressed;
|
|
722
1037
|
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
|
|
723
1038
|
return formatCapabilities;
|
|
724
1039
|
}
|
|
@@ -730,17 +1045,18 @@ function getTextureFormatInfo(format) {
|
|
|
730
1045
|
formatInfo.bytesPerPixel = 1;
|
|
731
1046
|
formatInfo.srgb = false;
|
|
732
1047
|
formatInfo.compressed = true;
|
|
1048
|
+
formatInfo.bytesPerBlock = getCompressedTextureBlockByteLength(format);
|
|
733
1049
|
const blockSize = getCompressedTextureBlockSize(format);
|
|
734
1050
|
if (blockSize) {
|
|
735
1051
|
formatInfo.blockWidth = blockSize.blockWidth;
|
|
736
1052
|
formatInfo.blockHeight = blockSize.blockHeight;
|
|
737
1053
|
}
|
|
738
1054
|
}
|
|
739
|
-
const matches = RGB_FORMAT_REGEX.exec(format);
|
|
1055
|
+
const matches = !formatInfo.packed ? RGB_FORMAT_REGEX.exec(format) : null;
|
|
740
1056
|
if (matches) {
|
|
741
1057
|
const [, channels, length, type, srgb, suffix] = matches;
|
|
742
1058
|
const dataType = `${type}${length}`;
|
|
743
|
-
const decodedType = getDataTypeInfo(dataType);
|
|
1059
|
+
const decodedType = dataTypeDecoder.getDataTypeInfo(dataType);
|
|
744
1060
|
const bits = decodedType.byteLength * 8;
|
|
745
1061
|
const components = (channels == null ? void 0 : channels.length) ?? 1;
|
|
746
1062
|
const bitsPerChannel = [
|
|
@@ -816,10 +1132,31 @@ function getCompressedTextureBlockSize(format) {
|
|
|
816
1132
|
const [, blockWidth, blockHeight] = matches;
|
|
817
1133
|
return { blockWidth: Number(blockWidth), blockHeight: Number(blockHeight) };
|
|
818
1134
|
}
|
|
1135
|
+
if (format.startsWith("bc") || format.startsWith("etc1") || format.startsWith("etc2") || format.startsWith("eac") || format.startsWith("atc")) {
|
|
1136
|
+
return { blockWidth: 4, blockHeight: 4 };
|
|
1137
|
+
}
|
|
1138
|
+
if (format.startsWith("pvrtc-rgb4") || format.startsWith("pvrtc-rgba4")) {
|
|
1139
|
+
return { blockWidth: 4, blockHeight: 4 };
|
|
1140
|
+
}
|
|
1141
|
+
if (format.startsWith("pvrtc-rgb2") || format.startsWith("pvrtc-rgba2")) {
|
|
1142
|
+
return { blockWidth: 8, blockHeight: 4 };
|
|
1143
|
+
}
|
|
819
1144
|
return null;
|
|
820
1145
|
}
|
|
1146
|
+
function getCompressedTextureBlockByteLength(format) {
|
|
1147
|
+
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") {
|
|
1148
|
+
return 8;
|
|
1149
|
+
}
|
|
1150
|
+
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") {
|
|
1151
|
+
return 16;
|
|
1152
|
+
}
|
|
1153
|
+
if (format.startsWith("pvrtc")) {
|
|
1154
|
+
return 8;
|
|
1155
|
+
}
|
|
1156
|
+
return 16;
|
|
1157
|
+
}
|
|
821
1158
|
|
|
822
|
-
// dist/image-
|
|
1159
|
+
// dist/shadertypes/image-types/image-types.js
|
|
823
1160
|
function isExternalImage(data) {
|
|
824
1161
|
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;
|
|
825
1162
|
}
|
|
@@ -842,6 +1179,53 @@ function getExternalImageSize(data) {
|
|
|
842
1179
|
// dist/adapter/device.js
|
|
843
1180
|
var DeviceLimits = class {
|
|
844
1181
|
};
|
|
1182
|
+
function formatErrorLogArguments(context, args) {
|
|
1183
|
+
const formattedContext = formatErrorLogValue(context);
|
|
1184
|
+
const formattedArgs = args.map(formatErrorLogValue).filter((arg) => arg !== void 0);
|
|
1185
|
+
return [formattedContext, ...formattedArgs].filter((arg) => arg !== void 0);
|
|
1186
|
+
}
|
|
1187
|
+
function formatErrorLogValue(value) {
|
|
1188
|
+
var _a;
|
|
1189
|
+
if (value === void 0) {
|
|
1190
|
+
return void 0;
|
|
1191
|
+
}
|
|
1192
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1193
|
+
return value;
|
|
1194
|
+
}
|
|
1195
|
+
if (value instanceof Error) {
|
|
1196
|
+
return value.message;
|
|
1197
|
+
}
|
|
1198
|
+
if (Array.isArray(value)) {
|
|
1199
|
+
return value.map(formatErrorLogValue);
|
|
1200
|
+
}
|
|
1201
|
+
if (typeof value === "object") {
|
|
1202
|
+
if (hasCustomToString(value)) {
|
|
1203
|
+
const stringValue = String(value);
|
|
1204
|
+
if (stringValue !== "[object Object]") {
|
|
1205
|
+
return stringValue;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
if (looksLikeGPUCompilationMessage(value)) {
|
|
1209
|
+
return formatGPUCompilationMessage(value);
|
|
1210
|
+
}
|
|
1211
|
+
return ((_a = value.constructor) == null ? void 0 : _a.name) || "Object";
|
|
1212
|
+
}
|
|
1213
|
+
return String(value);
|
|
1214
|
+
}
|
|
1215
|
+
function hasCustomToString(value) {
|
|
1216
|
+
return "toString" in value && typeof value.toString === "function" && value.toString !== Object.prototype.toString;
|
|
1217
|
+
}
|
|
1218
|
+
function looksLikeGPUCompilationMessage(value) {
|
|
1219
|
+
return "message" in value && "type" in value;
|
|
1220
|
+
}
|
|
1221
|
+
function formatGPUCompilationMessage(value) {
|
|
1222
|
+
const type = typeof value.type === "string" ? value.type : "message";
|
|
1223
|
+
const message = typeof value.message === "string" ? value.message : "";
|
|
1224
|
+
const lineNum = typeof value.lineNum === "number" ? value.lineNum : null;
|
|
1225
|
+
const linePos = typeof value.linePos === "number" ? value.linePos : null;
|
|
1226
|
+
const location = lineNum !== null && linePos !== null ? ` @ ${lineNum}:${linePos}` : lineNum !== null ? ` @ ${lineNum}` : "";
|
|
1227
|
+
return `${type}${location}: ${message}`.trim();
|
|
1228
|
+
}
|
|
845
1229
|
var DeviceFeatures = class {
|
|
846
1230
|
features;
|
|
847
1231
|
disabledFeatures;
|
|
@@ -872,6 +1256,8 @@ var _Device = class {
|
|
|
872
1256
|
userData = {};
|
|
873
1257
|
/** stats */
|
|
874
1258
|
statsManager = lumaStats;
|
|
1259
|
+
/** Internal per-device factory storage */
|
|
1260
|
+
_factories = {};
|
|
875
1261
|
/** An abstract timestamp used for change tracking */
|
|
876
1262
|
timestamp = 0;
|
|
877
1263
|
/** True if this device has been reused during device creation (app has multiple references) */
|
|
@@ -879,12 +1265,15 @@ var _Device = class {
|
|
|
879
1265
|
/** Used by other luma.gl modules to store data on the device */
|
|
880
1266
|
_moduleData = {};
|
|
881
1267
|
_textureCaps = {};
|
|
1268
|
+
/** Internal timestamp query set used when GPU timing collection is enabled for this device. */
|
|
1269
|
+
_debugGPUTimeQuery = null;
|
|
882
1270
|
constructor(props) {
|
|
883
1271
|
this.props = { ..._Device.defaultProps, ...props };
|
|
884
1272
|
this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
|
|
885
1273
|
}
|
|
1274
|
+
// TODO - just expose the shadertypes decoders?
|
|
886
1275
|
getVertexFormatInfo(format) {
|
|
887
|
-
return getVertexFormatInfo(format);
|
|
1276
|
+
return vertexFormatDecoder.getVertexFormatInfo(format);
|
|
888
1277
|
}
|
|
889
1278
|
isVertexFormatSupported(format) {
|
|
890
1279
|
return true;
|
|
@@ -932,6 +1321,16 @@ var _Device = class {
|
|
|
932
1321
|
isTextureFormatCompressed(format) {
|
|
933
1322
|
return textureFormatDecoder.isCompressed(format);
|
|
934
1323
|
}
|
|
1324
|
+
/** Returns the compressed texture formats that can be created and sampled on this device */
|
|
1325
|
+
getSupportedCompressedTextureFormats() {
|
|
1326
|
+
const supportedFormats = [];
|
|
1327
|
+
for (const format of Object.keys(getTextureFormatTable())) {
|
|
1328
|
+
if (this.isTextureFormatCompressed(format) && this.isTextureFormatSupported(format)) {
|
|
1329
|
+
supportedFormats.push(format);
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
return supportedFormats;
|
|
1333
|
+
}
|
|
935
1334
|
// DEBUG METHODS
|
|
936
1335
|
pushDebugGroup(groupLabel) {
|
|
937
1336
|
this.commandEncoder.pushDebugGroup(groupLabel);
|
|
@@ -976,7 +1375,8 @@ var _Device = class {
|
|
|
976
1375
|
reportError(error, context, ...args) {
|
|
977
1376
|
const isHandled = this.props.onError(error, context);
|
|
978
1377
|
if (!isHandled) {
|
|
979
|
-
|
|
1378
|
+
const logArguments = formatErrorLogArguments(context, args);
|
|
1379
|
+
return log.error(this.type === "webgl" ? "%cWebGL" : "%cWebGPU", "color: white; background: red; padding: 2px 6px; border-radius: 3px;", error.message, ...logArguments);
|
|
980
1380
|
}
|
|
981
1381
|
return () => {
|
|
982
1382
|
};
|
|
@@ -1010,6 +1410,78 @@ or create a device with the 'debug: true' prop.`;
|
|
|
1010
1410
|
beginComputePass(props) {
|
|
1011
1411
|
return this.commandEncoder.beginComputePass(props);
|
|
1012
1412
|
}
|
|
1413
|
+
/**
|
|
1414
|
+
* Generate mipmaps for a WebGPU texture.
|
|
1415
|
+
* WebGPU textures must be created up front with the required mip count, usage flags, and a format that supports the chosen generation path.
|
|
1416
|
+
* WebGL uses `Texture.generateMipmapsWebGL()` directly because the backend manages mip generation on the texture object itself.
|
|
1417
|
+
*/
|
|
1418
|
+
generateMipmapsWebGPU(_texture) {
|
|
1419
|
+
throw new Error("not implemented");
|
|
1420
|
+
}
|
|
1421
|
+
/** Internal helper for creating a shareable WebGL render-pipeline implementation. */
|
|
1422
|
+
_createSharedRenderPipelineWebGL(_props) {
|
|
1423
|
+
throw new Error("_createSharedRenderPipelineWebGL() not implemented");
|
|
1424
|
+
}
|
|
1425
|
+
/** Internal WebGPU-only helper for retrieving the native bind-group layout for a pipeline group. */
|
|
1426
|
+
_createBindGroupLayoutWebGPU(_pipeline, _group) {
|
|
1427
|
+
throw new Error("_createBindGroupLayoutWebGPU() not implemented");
|
|
1428
|
+
}
|
|
1429
|
+
/** Internal WebGPU-only helper for creating a native bind group. */
|
|
1430
|
+
_createBindGroupWebGPU(_bindGroupLayout, _shaderLayout, _bindings, _group) {
|
|
1431
|
+
throw new Error("_createBindGroupWebGPU() not implemented");
|
|
1432
|
+
}
|
|
1433
|
+
/**
|
|
1434
|
+
* Internal helper that returns `true` when timestamp-query GPU timing should be
|
|
1435
|
+
* collected for this device.
|
|
1436
|
+
*/
|
|
1437
|
+
_supportsDebugGPUTime() {
|
|
1438
|
+
return this.features.has("timestamp-query") && Boolean(this.props.debug || this.props.debugGPUTime);
|
|
1439
|
+
}
|
|
1440
|
+
/**
|
|
1441
|
+
* Internal helper that enables device-managed GPU timing collection on the
|
|
1442
|
+
* default command encoder. Reuses the existing query set if timing is already enabled.
|
|
1443
|
+
*
|
|
1444
|
+
* @param queryCount - Number of timestamp slots reserved for profiled passes.
|
|
1445
|
+
* @returns The device-managed timestamp QuerySet, or `null` when timing is not supported or could not be enabled.
|
|
1446
|
+
*/
|
|
1447
|
+
_enableDebugGPUTime(queryCount = 256) {
|
|
1448
|
+
if (!this._supportsDebugGPUTime()) {
|
|
1449
|
+
return null;
|
|
1450
|
+
}
|
|
1451
|
+
if (this._debugGPUTimeQuery) {
|
|
1452
|
+
return this._debugGPUTimeQuery;
|
|
1453
|
+
}
|
|
1454
|
+
try {
|
|
1455
|
+
this._debugGPUTimeQuery = this.createQuerySet({ type: "timestamp", count: queryCount });
|
|
1456
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
1457
|
+
id: this.commandEncoder.props.id,
|
|
1458
|
+
timeProfilingQuerySet: this._debugGPUTimeQuery
|
|
1459
|
+
});
|
|
1460
|
+
} catch {
|
|
1461
|
+
this._debugGPUTimeQuery = null;
|
|
1462
|
+
}
|
|
1463
|
+
return this._debugGPUTimeQuery;
|
|
1464
|
+
}
|
|
1465
|
+
/**
|
|
1466
|
+
* Internal helper that disables device-managed GPU timing collection and restores
|
|
1467
|
+
* the default command encoder to an unprofiled state.
|
|
1468
|
+
*/
|
|
1469
|
+
_disableDebugGPUTime() {
|
|
1470
|
+
if (!this._debugGPUTimeQuery) {
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
if (this.commandEncoder.getTimeProfilingQuerySet() === this._debugGPUTimeQuery) {
|
|
1474
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
1475
|
+
id: this.commandEncoder.props.id
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
this._debugGPUTimeQuery.destroy();
|
|
1479
|
+
this._debugGPUTimeQuery = null;
|
|
1480
|
+
}
|
|
1481
|
+
/** Internal helper that returns `true` when device-managed GPU timing is currently active. */
|
|
1482
|
+
_isDebugGPUTimeEnabled() {
|
|
1483
|
+
return this._debugGPUTimeQuery !== null;
|
|
1484
|
+
}
|
|
1013
1485
|
// DEPRECATED METHODS
|
|
1014
1486
|
/** @deprecated Use getDefaultCanvasContext() */
|
|
1015
1487
|
getCanvasContext() {
|
|
@@ -1117,7 +1589,8 @@ __publicField(Device, "defaultProps", {
|
|
|
1117
1589
|
onVisibilityChange: (context) => log.log(1, `${context} Visibility changed ${context.isVisible}`)(),
|
|
1118
1590
|
onDevicePixelRatioChange: (context, info) => log.log(1, `${context} DPR changed ${info.oldRatio} => ${context.devicePixelRatio}`)(),
|
|
1119
1591
|
// Debug flags
|
|
1120
|
-
debug:
|
|
1592
|
+
debug: getDefaultDebugValue(),
|
|
1593
|
+
debugGPUTime: false,
|
|
1121
1594
|
debugShaders: log.get("debug-shaders") || void 0,
|
|
1122
1595
|
debugFramebuffers: Boolean(log.get("debug-framebuffers")),
|
|
1123
1596
|
debugFactories: Boolean(log.get("debug-factories")),
|
|
@@ -1128,9 +1601,11 @@ __publicField(Device, "defaultProps", {
|
|
|
1128
1601
|
// Experimental
|
|
1129
1602
|
_reuseDevices: false,
|
|
1130
1603
|
_requestMaxLimits: true,
|
|
1131
|
-
_cacheShaders:
|
|
1132
|
-
|
|
1133
|
-
|
|
1604
|
+
_cacheShaders: true,
|
|
1605
|
+
_destroyShaders: false,
|
|
1606
|
+
_cachePipelines: true,
|
|
1607
|
+
_sharePipelines: true,
|
|
1608
|
+
_destroyPipelines: false,
|
|
1134
1609
|
// TODO - Change these after confirming things work as expected
|
|
1135
1610
|
_initializeFeatures: true,
|
|
1136
1611
|
_disabledFeatures: {
|
|
@@ -1139,6 +1614,25 @@ __publicField(Device, "defaultProps", {
|
|
|
1139
1614
|
// INTERNAL
|
|
1140
1615
|
_handle: void 0
|
|
1141
1616
|
});
|
|
1617
|
+
function _getDefaultDebugValue(logDebugValue, nodeEnv) {
|
|
1618
|
+
if (logDebugValue !== void 0 && logDebugValue !== null) {
|
|
1619
|
+
return Boolean(logDebugValue);
|
|
1620
|
+
}
|
|
1621
|
+
if (nodeEnv !== void 0) {
|
|
1622
|
+
return nodeEnv !== "production";
|
|
1623
|
+
}
|
|
1624
|
+
return false;
|
|
1625
|
+
}
|
|
1626
|
+
function getDefaultDebugValue() {
|
|
1627
|
+
return _getDefaultDebugValue(log.get("debug"), getNodeEnv());
|
|
1628
|
+
}
|
|
1629
|
+
function getNodeEnv() {
|
|
1630
|
+
const processObject = globalThis.process;
|
|
1631
|
+
if (!(processObject == null ? void 0 : processObject.env)) {
|
|
1632
|
+
return void 0;
|
|
1633
|
+
}
|
|
1634
|
+
return processObject.env["NODE_ENV"];
|
|
1635
|
+
}
|
|
1142
1636
|
|
|
1143
1637
|
// dist/adapter/luma.js
|
|
1144
1638
|
var STARTUP_MESSAGE = "set luma.log.level=1 (or higher) to trace rendering";
|
|
@@ -1158,7 +1652,7 @@ var _Luma = class {
|
|
|
1158
1652
|
VERSION = (
|
|
1159
1653
|
// Version detection using build plugin
|
|
1160
1654
|
// @ts-expect-error no-undef
|
|
1161
|
-
true ? "9.3.0-alpha.
|
|
1655
|
+
true ? "9.3.0-alpha.8" : "running from source"
|
|
1162
1656
|
);
|
|
1163
1657
|
spector;
|
|
1164
1658
|
preregisteredAdapters = /* @__PURE__ */ new Map();
|
|
@@ -1323,9 +1817,91 @@ function getPageLoadPromise() {
|
|
|
1323
1817
|
return pageLoadPromise;
|
|
1324
1818
|
}
|
|
1325
1819
|
|
|
1326
|
-
// dist/adapter/canvas-
|
|
1820
|
+
// dist/adapter/canvas-surface.js
|
|
1327
1821
|
var import_env2 = require("@probe.gl/env");
|
|
1328
1822
|
|
|
1823
|
+
// dist/adapter/canvas-observer.js
|
|
1824
|
+
var CanvasObserver = class {
|
|
1825
|
+
props;
|
|
1826
|
+
_resizeObserver;
|
|
1827
|
+
_intersectionObserver;
|
|
1828
|
+
_observeDevicePixelRatioTimeout = null;
|
|
1829
|
+
_observeDevicePixelRatioMediaQuery = null;
|
|
1830
|
+
_handleDevicePixelRatioChange = () => this._refreshDevicePixelRatio();
|
|
1831
|
+
_trackPositionInterval = null;
|
|
1832
|
+
_started = false;
|
|
1833
|
+
get started() {
|
|
1834
|
+
return this._started;
|
|
1835
|
+
}
|
|
1836
|
+
constructor(props) {
|
|
1837
|
+
this.props = props;
|
|
1838
|
+
}
|
|
1839
|
+
start() {
|
|
1840
|
+
if (this._started || !this.props.canvas) {
|
|
1841
|
+
return;
|
|
1842
|
+
}
|
|
1843
|
+
this._started = true;
|
|
1844
|
+
this._intersectionObserver ||= new IntersectionObserver((entries) => this.props.onIntersection(entries));
|
|
1845
|
+
this._resizeObserver ||= new ResizeObserver((entries) => this.props.onResize(entries));
|
|
1846
|
+
this._intersectionObserver.observe(this.props.canvas);
|
|
1847
|
+
try {
|
|
1848
|
+
this._resizeObserver.observe(this.props.canvas, { box: "device-pixel-content-box" });
|
|
1849
|
+
} catch {
|
|
1850
|
+
this._resizeObserver.observe(this.props.canvas, { box: "content-box" });
|
|
1851
|
+
}
|
|
1852
|
+
this._observeDevicePixelRatioTimeout = setTimeout(() => this._refreshDevicePixelRatio(), 0);
|
|
1853
|
+
if (this.props.trackPosition) {
|
|
1854
|
+
this._trackPosition();
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
stop() {
|
|
1858
|
+
var _a, _b;
|
|
1859
|
+
if (!this._started) {
|
|
1860
|
+
return;
|
|
1861
|
+
}
|
|
1862
|
+
this._started = false;
|
|
1863
|
+
if (this._observeDevicePixelRatioTimeout) {
|
|
1864
|
+
clearTimeout(this._observeDevicePixelRatioTimeout);
|
|
1865
|
+
this._observeDevicePixelRatioTimeout = null;
|
|
1866
|
+
}
|
|
1867
|
+
if (this._observeDevicePixelRatioMediaQuery) {
|
|
1868
|
+
this._observeDevicePixelRatioMediaQuery.removeEventListener("change", this._handleDevicePixelRatioChange);
|
|
1869
|
+
this._observeDevicePixelRatioMediaQuery = null;
|
|
1870
|
+
}
|
|
1871
|
+
if (this._trackPositionInterval) {
|
|
1872
|
+
clearInterval(this._trackPositionInterval);
|
|
1873
|
+
this._trackPositionInterval = null;
|
|
1874
|
+
}
|
|
1875
|
+
(_a = this._resizeObserver) == null ? void 0 : _a.disconnect();
|
|
1876
|
+
(_b = this._intersectionObserver) == null ? void 0 : _b.disconnect();
|
|
1877
|
+
}
|
|
1878
|
+
_refreshDevicePixelRatio() {
|
|
1879
|
+
var _a;
|
|
1880
|
+
if (!this._started) {
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1883
|
+
this.props.onDevicePixelRatioChange();
|
|
1884
|
+
(_a = this._observeDevicePixelRatioMediaQuery) == null ? void 0 : _a.removeEventListener("change", this._handleDevicePixelRatioChange);
|
|
1885
|
+
this._observeDevicePixelRatioMediaQuery = matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
1886
|
+
this._observeDevicePixelRatioMediaQuery.addEventListener("change", this._handleDevicePixelRatioChange, { once: true });
|
|
1887
|
+
}
|
|
1888
|
+
_trackPosition(intervalMs = 100) {
|
|
1889
|
+
if (this._trackPositionInterval) {
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1892
|
+
this._trackPositionInterval = setInterval(() => {
|
|
1893
|
+
if (!this._started) {
|
|
1894
|
+
if (this._trackPositionInterval) {
|
|
1895
|
+
clearInterval(this._trackPositionInterval);
|
|
1896
|
+
this._trackPositionInterval = null;
|
|
1897
|
+
}
|
|
1898
|
+
} else {
|
|
1899
|
+
this.props.onPositionChange();
|
|
1900
|
+
}
|
|
1901
|
+
}, intervalMs);
|
|
1902
|
+
}
|
|
1903
|
+
};
|
|
1904
|
+
|
|
1329
1905
|
// dist/utils/promise-utils.js
|
|
1330
1906
|
function withResolvers() {
|
|
1331
1907
|
let resolve;
|
|
@@ -1351,8 +1927,8 @@ function assertDefined(value, message) {
|
|
|
1351
1927
|
return value;
|
|
1352
1928
|
}
|
|
1353
1929
|
|
|
1354
|
-
// dist/adapter/canvas-
|
|
1355
|
-
var
|
|
1930
|
+
// dist/adapter/canvas-surface.js
|
|
1931
|
+
var _CanvasSurface = class {
|
|
1356
1932
|
static isHTMLCanvas(canvas) {
|
|
1357
1933
|
return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
|
|
1358
1934
|
}
|
|
@@ -1388,11 +1964,7 @@ var _CanvasContext = class {
|
|
|
1388
1964
|
drawingBufferHeight;
|
|
1389
1965
|
/** Resolves when the canvas is initialized, i.e. when the ResizeObserver has updated the pixel size */
|
|
1390
1966
|
_initializedResolvers = withResolvers();
|
|
1391
|
-
|
|
1392
|
-
_resizeObserver;
|
|
1393
|
-
/** IntersectionObserver to track canvas visibility changes */
|
|
1394
|
-
_intersectionObserver;
|
|
1395
|
-
_observeDevicePixelRatioTimeout = null;
|
|
1967
|
+
_canvasObserver;
|
|
1396
1968
|
/** Position of the canvas in the document, updated by a timer */
|
|
1397
1969
|
_position = [0, 0];
|
|
1398
1970
|
/** Whether this canvas context has been destroyed */
|
|
@@ -1404,7 +1976,7 @@ var _CanvasContext = class {
|
|
|
1404
1976
|
}
|
|
1405
1977
|
constructor(props) {
|
|
1406
1978
|
var _a, _b;
|
|
1407
|
-
this.props = { ...
|
|
1979
|
+
this.props = { ..._CanvasSurface.defaultProps, ...props };
|
|
1408
1980
|
props = this.props;
|
|
1409
1981
|
this.initialized = this._initializedResolvers.promise;
|
|
1410
1982
|
if (!(0, import_env2.isBrowser)()) {
|
|
@@ -1416,11 +1988,11 @@ var _CanvasContext = class {
|
|
|
1416
1988
|
} else {
|
|
1417
1989
|
this.canvas = props.canvas;
|
|
1418
1990
|
}
|
|
1419
|
-
if (
|
|
1991
|
+
if (_CanvasSurface.isHTMLCanvas(this.canvas)) {
|
|
1420
1992
|
this.id = props.id || this.canvas.id;
|
|
1421
1993
|
this.type = "html-canvas";
|
|
1422
1994
|
this.htmlCanvas = this.canvas;
|
|
1423
|
-
} else if (
|
|
1995
|
+
} else if (_CanvasSurface.isOffscreenCanvas(this.canvas)) {
|
|
1424
1996
|
this.id = props.id || "offscreen-canvas";
|
|
1425
1997
|
this.type = "offscreen-canvas";
|
|
1426
1998
|
this.offscreenCanvas = this.canvas;
|
|
@@ -1436,32 +2008,20 @@ var _CanvasContext = class {
|
|
|
1436
2008
|
this.drawingBufferHeight = this.canvas.height;
|
|
1437
2009
|
this.devicePixelRatio = globalThis.devicePixelRatio || 1;
|
|
1438
2010
|
this._position = [0, 0];
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
this.
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
}
|
|
1448
|
-
this._observeDevicePixelRatioTimeout = setTimeout(() => this._observeDevicePixelRatio(), 0);
|
|
1449
|
-
if (this.props.trackPosition) {
|
|
1450
|
-
this._trackPosition();
|
|
1451
|
-
}
|
|
1452
|
-
}
|
|
2011
|
+
this._canvasObserver = new CanvasObserver({
|
|
2012
|
+
canvas: this.htmlCanvas,
|
|
2013
|
+
trackPosition: this.props.trackPosition,
|
|
2014
|
+
onResize: (entries) => this._handleResize(entries),
|
|
2015
|
+
onIntersection: (entries) => this._handleIntersection(entries),
|
|
2016
|
+
onDevicePixelRatioChange: () => this._observeDevicePixelRatio(),
|
|
2017
|
+
onPositionChange: () => this.updatePosition()
|
|
2018
|
+
});
|
|
1453
2019
|
}
|
|
1454
2020
|
destroy() {
|
|
1455
|
-
var _a, _b;
|
|
1456
2021
|
if (!this.destroyed) {
|
|
1457
2022
|
this.destroyed = true;
|
|
1458
|
-
|
|
1459
|
-
clearTimeout(this._observeDevicePixelRatioTimeout);
|
|
1460
|
-
this._observeDevicePixelRatioTimeout = null;
|
|
1461
|
-
}
|
|
2023
|
+
this._stopObservers();
|
|
1462
2024
|
this.device = null;
|
|
1463
|
-
(_a = this._resizeObserver) == null ? void 0 : _a.disconnect();
|
|
1464
|
-
(_b = this._intersectionObserver) == null ? void 0 : _b.disconnect();
|
|
1465
2025
|
}
|
|
1466
2026
|
}
|
|
1467
2027
|
setProps(props) {
|
|
@@ -1476,41 +2036,22 @@ var _CanvasContext = class {
|
|
|
1476
2036
|
this._resizeDrawingBufferIfNeeded();
|
|
1477
2037
|
return this._getCurrentFramebuffer(options);
|
|
1478
2038
|
}
|
|
1479
|
-
// SIZE METHODS
|
|
1480
|
-
/**
|
|
1481
|
-
* Returns the size covered by the canvas in CSS pixels
|
|
1482
|
-
* @note This can be different from the actual device pixel size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
1483
|
-
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
1484
|
-
*/
|
|
1485
2039
|
getCSSSize() {
|
|
1486
2040
|
return [this.cssWidth, this.cssHeight];
|
|
1487
2041
|
}
|
|
1488
2042
|
getPosition() {
|
|
1489
2043
|
return this._position;
|
|
1490
2044
|
}
|
|
1491
|
-
/**
|
|
1492
|
-
* Returns the size covered by the canvas in actual device pixels.
|
|
1493
|
-
* @note This can be different from the 'CSS' size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
1494
|
-
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
1495
|
-
*/
|
|
1496
2045
|
getDevicePixelSize() {
|
|
1497
2046
|
return [this.devicePixelWidth, this.devicePixelHeight];
|
|
1498
2047
|
}
|
|
1499
|
-
/** Get the drawing buffer size (number of pixels GPU is rendering into, can be different from CSS size) */
|
|
1500
2048
|
getDrawingBufferSize() {
|
|
1501
2049
|
return [this.drawingBufferWidth, this.drawingBufferHeight];
|
|
1502
2050
|
}
|
|
1503
|
-
/** Returns the biggest allowed framebuffer size. @todo Allow the application to limit this? */
|
|
1504
2051
|
getMaxDrawingBufferSize() {
|
|
1505
2052
|
const maxTextureDimension = this.device.limits.maxTextureDimension2D;
|
|
1506
2053
|
return [maxTextureDimension, maxTextureDimension];
|
|
1507
2054
|
}
|
|
1508
|
-
/**
|
|
1509
|
-
* Update the canvas drawing buffer size.
|
|
1510
|
-
* @note - Called automatically if props.autoResize is true.
|
|
1511
|
-
* @note - Defers update of drawing buffer size until framebuffer is requested to avoid flicker
|
|
1512
|
-
* (resizing clears the drawing buffer)!
|
|
1513
|
-
*/
|
|
1514
2055
|
setDrawingBufferSize(width, height) {
|
|
1515
2056
|
width = Math.floor(width);
|
|
1516
2057
|
height = Math.floor(height);
|
|
@@ -1521,19 +2062,10 @@ var _CanvasContext = class {
|
|
|
1521
2062
|
this.drawingBufferHeight = height;
|
|
1522
2063
|
this._needsDrawingBufferResize = true;
|
|
1523
2064
|
}
|
|
1524
|
-
/**
|
|
1525
|
-
* Returns the current DPR (number of physical pixels per CSS pixel), if props.useDevicePixels is true
|
|
1526
|
-
* @note This can be a fractional (non-integer) number, e.g. when the user zooms in the browser.
|
|
1527
|
-
* @note This function handles the non-HTML canvas cases
|
|
1528
|
-
*/
|
|
1529
2065
|
getDevicePixelRatio() {
|
|
1530
|
-
const
|
|
1531
|
-
return
|
|
2066
|
+
const devicePixelRatio2 = typeof window !== "undefined" && window.devicePixelRatio;
|
|
2067
|
+
return devicePixelRatio2 || 1;
|
|
1532
2068
|
}
|
|
1533
|
-
// DEPRECATED METHODS
|
|
1534
|
-
/**
|
|
1535
|
-
* Maps CSS pixel position to device pixel position
|
|
1536
|
-
*/
|
|
1537
2069
|
cssToDevicePixels(cssPixel, yInvert = true) {
|
|
1538
2070
|
const ratio = this.cssToDeviceRatio();
|
|
1539
2071
|
const [width, height] = this.getDrawingBufferSize();
|
|
@@ -1543,10 +2075,10 @@ var _CanvasContext = class {
|
|
|
1543
2075
|
getPixelSize() {
|
|
1544
2076
|
return this.getDevicePixelSize();
|
|
1545
2077
|
}
|
|
1546
|
-
/** @deprecated
|
|
2078
|
+
/** @deprecated Use the current drawing buffer size for projection setup. */
|
|
1547
2079
|
getAspect() {
|
|
1548
|
-
const [width, height] = this.
|
|
1549
|
-
return width / height;
|
|
2080
|
+
const [width, height] = this.getDrawingBufferSize();
|
|
2081
|
+
return width > 0 && height > 0 ? width / height : 1;
|
|
1550
2082
|
}
|
|
1551
2083
|
/** @deprecated Returns multiplier need to convert CSS size to Device size */
|
|
1552
2084
|
cssToDeviceRatio() {
|
|
@@ -1562,18 +2094,37 @@ var _CanvasContext = class {
|
|
|
1562
2094
|
resize(size) {
|
|
1563
2095
|
this.setDrawingBufferSize(size.width, size.height);
|
|
1564
2096
|
}
|
|
1565
|
-
// IMPLEMENTATION
|
|
1566
|
-
/**
|
|
1567
|
-
* Allows subclass constructor to override the canvas id for auto created canvases.
|
|
1568
|
-
* This can really help when debugging DOM in apps that create multiple devices
|
|
1569
|
-
*/
|
|
1570
2097
|
_setAutoCreatedCanvasId(id) {
|
|
1571
2098
|
var _a;
|
|
1572
2099
|
if (((_a = this.htmlCanvas) == null ? void 0 : _a.id) === "lumagl-auto-created-canvas") {
|
|
1573
2100
|
this.htmlCanvas.id = id;
|
|
1574
2101
|
}
|
|
1575
2102
|
}
|
|
1576
|
-
/**
|
|
2103
|
+
/**
|
|
2104
|
+
* Starts DOM observation after the derived context and its device are fully initialized.
|
|
2105
|
+
*
|
|
2106
|
+
* `CanvasSurface` construction runs before subclasses can assign `this.device`, and the
|
|
2107
|
+
* default WebGL canvas context is created before `WebGLDevice` has initialized `limits`,
|
|
2108
|
+
* `features`, and the rest of its runtime state. Deferring observer startup avoids early
|
|
2109
|
+
* `ResizeObserver` and DPR callbacks running against a partially initialized device.
|
|
2110
|
+
*/
|
|
2111
|
+
_startObservers() {
|
|
2112
|
+
if (this.destroyed) {
|
|
2113
|
+
return;
|
|
2114
|
+
}
|
|
2115
|
+
this._canvasObserver.start();
|
|
2116
|
+
}
|
|
2117
|
+
/**
|
|
2118
|
+
* Stops all DOM observation and timers associated with a canvas surface.
|
|
2119
|
+
*
|
|
2120
|
+
* This pairs with `_startObservers()` so teardown uses the same lifecycle whether a context is
|
|
2121
|
+
* explicitly destroyed, abandoned during device reuse, or temporarily has not started observing
|
|
2122
|
+
* yet. Centralizing shutdown here keeps resize/DPR/position watchers from surviving past the
|
|
2123
|
+
* lifetime of the owning device.
|
|
2124
|
+
*/
|
|
2125
|
+
_stopObservers() {
|
|
2126
|
+
this._canvasObserver.stop();
|
|
2127
|
+
}
|
|
1577
2128
|
_handleIntersection(entries) {
|
|
1578
2129
|
if (this.destroyed) {
|
|
1579
2130
|
return;
|
|
@@ -1588,11 +2139,6 @@ var _CanvasContext = class {
|
|
|
1588
2139
|
this.device.props.onVisibilityChange(this);
|
|
1589
2140
|
}
|
|
1590
2141
|
}
|
|
1591
|
-
/**
|
|
1592
|
-
* Reacts to an observed resize by using the most accurate pixel size information the browser can provide
|
|
1593
|
-
* @see https://web.dev/articles/device-pixel-content-box
|
|
1594
|
-
* @see https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html
|
|
1595
|
-
*/
|
|
1596
2142
|
_handleResize(entries) {
|
|
1597
2143
|
var _a, _b, _c, _d, _e;
|
|
1598
2144
|
if (this.destroyed) {
|
|
@@ -1614,12 +2160,11 @@ var _CanvasContext = class {
|
|
|
1614
2160
|
this._updateDrawingBufferSize();
|
|
1615
2161
|
this.device.props.onResize(this, { oldPixelSize });
|
|
1616
2162
|
}
|
|
1617
|
-
/** Initiate a deferred update for the canvas drawing buffer size */
|
|
1618
2163
|
_updateDrawingBufferSize() {
|
|
1619
2164
|
if (this.props.autoResize) {
|
|
1620
2165
|
if (typeof this.props.useDevicePixels === "number") {
|
|
1621
|
-
const
|
|
1622
|
-
this.setDrawingBufferSize(this.cssWidth *
|
|
2166
|
+
const devicePixelRatio2 = this.props.useDevicePixels;
|
|
2167
|
+
this.setDrawingBufferSize(this.cssWidth * devicePixelRatio2, this.cssHeight * devicePixelRatio2);
|
|
1623
2168
|
} else if (this.props.useDevicePixels) {
|
|
1624
2169
|
this.setDrawingBufferSize(this.devicePixelWidth, this.devicePixelHeight);
|
|
1625
2170
|
} else {
|
|
@@ -1630,7 +2175,6 @@ var _CanvasContext = class {
|
|
|
1630
2175
|
this.isInitialized = true;
|
|
1631
2176
|
this.updatePosition();
|
|
1632
2177
|
}
|
|
1633
|
-
/** Perform a deferred resize of the drawing buffer if needed */
|
|
1634
2178
|
_resizeDrawingBufferIfNeeded() {
|
|
1635
2179
|
if (this._needsDrawingBufferResize) {
|
|
1636
2180
|
this._needsDrawingBufferResize = false;
|
|
@@ -1642,33 +2186,18 @@ var _CanvasContext = class {
|
|
|
1642
2186
|
}
|
|
1643
2187
|
}
|
|
1644
2188
|
}
|
|
1645
|
-
/** Monitor DPR changes */
|
|
1646
2189
|
_observeDevicePixelRatio() {
|
|
1647
2190
|
var _a, _b;
|
|
1648
|
-
if (this.destroyed) {
|
|
2191
|
+
if (this.destroyed || !this._canvasObserver.started) {
|
|
1649
2192
|
return;
|
|
1650
2193
|
}
|
|
1651
2194
|
const oldRatio = this.devicePixelRatio;
|
|
1652
2195
|
this.devicePixelRatio = window.devicePixelRatio;
|
|
1653
2196
|
this.updatePosition();
|
|
1654
|
-
(_b = (_a = this.device.props).onDevicePixelRatioChange) == null ? void 0 : _b.call(_a, this, {
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
/** Start tracking positions with a timer */
|
|
1658
|
-
_trackPosition(intervalMs = 100) {
|
|
1659
|
-
const intervalId = setInterval(() => {
|
|
1660
|
-
if (this.destroyed) {
|
|
1661
|
-
clearInterval(intervalId);
|
|
1662
|
-
} else {
|
|
1663
|
-
this.updatePosition();
|
|
1664
|
-
}
|
|
1665
|
-
}, intervalMs);
|
|
2197
|
+
(_b = (_a = this.device.props).onDevicePixelRatioChange) == null ? void 0 : _b.call(_a, this, {
|
|
2198
|
+
oldRatio
|
|
2199
|
+
});
|
|
1666
2200
|
}
|
|
1667
|
-
/**
|
|
1668
|
-
* Calculated the absolute position of the canvas
|
|
1669
|
-
* @note - getBoundingClientRect() is normally cheap but can be expensive
|
|
1670
|
-
* if called before browser has finished a reflow. Should not be the case here.
|
|
1671
|
-
*/
|
|
1672
2201
|
updatePosition() {
|
|
1673
2202
|
var _a, _b, _c;
|
|
1674
2203
|
if (this.destroyed) {
|
|
@@ -1682,13 +2211,15 @@ var _CanvasContext = class {
|
|
|
1682
2211
|
if (positionChanged) {
|
|
1683
2212
|
const oldPosition = this._position;
|
|
1684
2213
|
this._position = position;
|
|
1685
|
-
(_c = (_b = this.device.props).onPositionChange) == null ? void 0 : _c.call(_b, this, {
|
|
2214
|
+
(_c = (_b = this.device.props).onPositionChange) == null ? void 0 : _c.call(_b, this, {
|
|
2215
|
+
oldPosition
|
|
2216
|
+
});
|
|
1686
2217
|
}
|
|
1687
2218
|
}
|
|
1688
2219
|
}
|
|
1689
2220
|
};
|
|
1690
|
-
var
|
|
1691
|
-
__publicField(
|
|
2221
|
+
var CanvasSurface = _CanvasSurface;
|
|
2222
|
+
__publicField(CanvasSurface, "defaultProps", {
|
|
1692
2223
|
id: void 0,
|
|
1693
2224
|
canvas: null,
|
|
1694
2225
|
width: 800,
|
|
@@ -1716,7 +2247,7 @@ function getContainer(container) {
|
|
|
1716
2247
|
}
|
|
1717
2248
|
function getCanvasFromDOM(canvasId) {
|
|
1718
2249
|
const canvas = document.getElementById(canvasId);
|
|
1719
|
-
if (!
|
|
2250
|
+
if (!CanvasSurface.isHTMLCanvas(canvas)) {
|
|
1720
2251
|
throw new Error("Object is not a canvas element");
|
|
1721
2252
|
}
|
|
1722
2253
|
return canvas;
|
|
@@ -1740,33 +2271,40 @@ function scalePixels(pixel, ratio, width, height, yInvert) {
|
|
|
1740
2271
|
const point = pixel;
|
|
1741
2272
|
const x = scaleX(point[0], ratio, width);
|
|
1742
2273
|
let y = scaleY(point[1], ratio, height, yInvert);
|
|
1743
|
-
let
|
|
1744
|
-
const xHigh =
|
|
1745
|
-
|
|
2274
|
+
let temporary = scaleX(point[0] + 1, ratio, width);
|
|
2275
|
+
const xHigh = temporary === width - 1 ? temporary : temporary - 1;
|
|
2276
|
+
temporary = scaleY(point[1] + 1, ratio, height, yInvert);
|
|
1746
2277
|
let yHigh;
|
|
1747
2278
|
if (yInvert) {
|
|
1748
|
-
|
|
2279
|
+
temporary = temporary === 0 ? temporary : temporary + 1;
|
|
1749
2280
|
yHigh = y;
|
|
1750
|
-
y =
|
|
2281
|
+
y = temporary;
|
|
1751
2282
|
} else {
|
|
1752
|
-
yHigh =
|
|
2283
|
+
yHigh = temporary === height - 1 ? temporary : temporary - 1;
|
|
1753
2284
|
}
|
|
1754
2285
|
return {
|
|
1755
2286
|
x,
|
|
1756
2287
|
y,
|
|
1757
|
-
// when ratio < 1, current css pixel and next css pixel may point to same device pixel, set width/height to 1 in those cases.
|
|
1758
2288
|
width: Math.max(xHigh - x + 1, 1),
|
|
1759
2289
|
height: Math.max(yHigh - y + 1, 1)
|
|
1760
2290
|
};
|
|
1761
2291
|
}
|
|
1762
2292
|
function scaleX(x, ratio, width) {
|
|
1763
|
-
|
|
1764
|
-
return r;
|
|
2293
|
+
return Math.min(Math.round(x * ratio), width - 1);
|
|
1765
2294
|
}
|
|
1766
2295
|
function scaleY(y, ratio, height, yInvert) {
|
|
1767
2296
|
return yInvert ? Math.max(0, height - 1 - Math.round(y * ratio)) : Math.min(Math.round(y * ratio), height - 1);
|
|
1768
2297
|
}
|
|
1769
2298
|
|
|
2299
|
+
// dist/adapter/canvas-context.js
|
|
2300
|
+
var CanvasContext = class extends CanvasSurface {
|
|
2301
|
+
};
|
|
2302
|
+
__publicField(CanvasContext, "defaultProps", CanvasSurface.defaultProps);
|
|
2303
|
+
|
|
2304
|
+
// dist/adapter/presentation-context.js
|
|
2305
|
+
var PresentationContext = class extends CanvasSurface {
|
|
2306
|
+
};
|
|
2307
|
+
|
|
1770
2308
|
// dist/adapter/resources/sampler.js
|
|
1771
2309
|
var _Sampler = class extends Resource {
|
|
1772
2310
|
get [Symbol.toStringTag]() {
|
|
@@ -1821,6 +2359,8 @@ var _Texture = class extends Resource {
|
|
|
1821
2359
|
depth;
|
|
1822
2360
|
/** mip levels in this texture */
|
|
1823
2361
|
mipLevels;
|
|
2362
|
+
/** sample count */
|
|
2363
|
+
samples;
|
|
1824
2364
|
/** Rows are multiples of this length, padded with extra bytes if needed */
|
|
1825
2365
|
byteAlignment;
|
|
1826
2366
|
/** The ready promise is always resolved. It is provided for type compatibility with DynamicTexture. */
|
|
@@ -1846,6 +2386,7 @@ var _Texture = class extends Resource {
|
|
|
1846
2386
|
this.height = this.props.height;
|
|
1847
2387
|
this.depth = this.props.depth;
|
|
1848
2388
|
this.mipLevels = this.props.mipLevels;
|
|
2389
|
+
this.samples = this.props.samples || 1;
|
|
1849
2390
|
if (this.dimension === "cube") {
|
|
1850
2391
|
this.depth = 6;
|
|
1851
2392
|
}
|
|
@@ -1877,9 +2418,25 @@ var _Texture = class extends Resource {
|
|
|
1877
2418
|
setSampler(sampler) {
|
|
1878
2419
|
this.sampler = sampler instanceof Sampler ? sampler : this.device.createSampler(sampler);
|
|
1879
2420
|
}
|
|
2421
|
+
/**
|
|
2422
|
+
* Copy raw image data (bytes) into the texture.
|
|
2423
|
+
*
|
|
2424
|
+
* @note Deprecated compatibility wrapper over {@link writeData}.
|
|
2425
|
+
* @note Uses the same layout defaults and alignment rules as {@link writeData}.
|
|
2426
|
+
* @note Tightly packed CPU uploads can omit `bytesPerRow` and `rowsPerImage`.
|
|
2427
|
+
* @note If the CPU source rows are padded, pass explicit `bytesPerRow` and `rowsPerImage`.
|
|
2428
|
+
* @deprecated Use writeData()
|
|
2429
|
+
*/
|
|
2430
|
+
copyImageData(options) {
|
|
2431
|
+
const { data, depth, ...writeOptions } = options;
|
|
2432
|
+
this.writeData(data, {
|
|
2433
|
+
...writeOptions,
|
|
2434
|
+
depthOrArrayLayers: writeOptions.depthOrArrayLayers ?? depth
|
|
2435
|
+
});
|
|
2436
|
+
}
|
|
1880
2437
|
/**
|
|
1881
2438
|
* Calculates the memory layout of the texture, required when reading and writing data.
|
|
1882
|
-
* @return the
|
|
2439
|
+
* @return the backend-aligned linear layout, in particular bytesPerRow which includes any required padding for buffer copy/read paths
|
|
1883
2440
|
*/
|
|
1884
2441
|
computeMemoryLayout(options_ = {}) {
|
|
1885
2442
|
const options = this._normalizeTextureReadOptions(options_);
|
|
@@ -1898,9 +2455,11 @@ var _Texture = class extends Resource {
|
|
|
1898
2455
|
* @returns A Buffer containing the texture data.
|
|
1899
2456
|
*
|
|
1900
2457
|
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
1901
|
-
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
1902
|
-
* @note The application can call Buffer.readAsync()
|
|
1903
|
-
* @note
|
|
2458
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the backend-aligned layout.
|
|
2459
|
+
* @note The application can call Buffer.readAsync() to read the returned buffer on the CPU.
|
|
2460
|
+
* @note The destination buffer must be supplied by the caller and must be large enough for the requested region.
|
|
2461
|
+
* @note On WebGPU this corresponds to a texture-to-buffer copy and uses buffer-copy alignment rules.
|
|
2462
|
+
* @note On WebGL, luma.gl emulates the same logical readback behavior.
|
|
1904
2463
|
*/
|
|
1905
2464
|
readBuffer(options, buffer) {
|
|
1906
2465
|
throw new Error("readBuffer not implemented");
|
|
@@ -1911,15 +2470,20 @@ var _Texture = class extends Resource {
|
|
|
1911
2470
|
*
|
|
1912
2471
|
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
1913
2472
|
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
2473
|
+
* @deprecated Use Texture.readBuffer() with an explicit destination buffer, or DynamicTexture.readAsync() for convenience readback.
|
|
1914
2474
|
*/
|
|
1915
2475
|
readDataAsync(options) {
|
|
1916
2476
|
throw new Error("readBuffer not implemented");
|
|
1917
2477
|
}
|
|
1918
2478
|
/**
|
|
1919
|
-
* Writes
|
|
2479
|
+
* Writes a GPU Buffer into a texture.
|
|
1920
2480
|
*
|
|
2481
|
+
* @param buffer - Source GPU buffer.
|
|
2482
|
+
* @param options - Destination subresource, extent, and source layout options.
|
|
1921
2483
|
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
1922
|
-
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
2484
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the backend-aligned layout.
|
|
2485
|
+
* @note On WebGPU this corresponds to a buffer-to-texture copy and uses buffer-copy alignment rules.
|
|
2486
|
+
* @note On WebGL, luma.gl emulates the same destination and layout semantics.
|
|
1923
2487
|
*/
|
|
1924
2488
|
writeBuffer(buffer, options) {
|
|
1925
2489
|
throw new Error("readBuffer not implemented");
|
|
@@ -1927,8 +2491,11 @@ var _Texture = class extends Resource {
|
|
|
1927
2491
|
/**
|
|
1928
2492
|
* Writes an array buffer into a texture.
|
|
1929
2493
|
*
|
|
1930
|
-
* @
|
|
1931
|
-
* @
|
|
2494
|
+
* @param data - Source texel data.
|
|
2495
|
+
* @param options - Destination subresource, extent, and source layout options.
|
|
2496
|
+
* @note If `bytesPerRow` and `rowsPerImage` are omitted, luma.gl computes a tightly packed CPU-memory layout for the requested region.
|
|
2497
|
+
* @note On WebGPU this corresponds to `GPUQueue.writeTexture()` and does not implicitly pad rows to 256 bytes.
|
|
2498
|
+
* @note On WebGL, padded CPU data is supported via the same `bytesPerRow` and `rowsPerImage` options.
|
|
1932
2499
|
*/
|
|
1933
2500
|
writeData(data, options) {
|
|
1934
2501
|
throw new Error("readBuffer not implemented");
|
|
@@ -1991,37 +2558,148 @@ var _Texture = class extends Resource {
|
|
|
1991
2558
|
}
|
|
1992
2559
|
}
|
|
1993
2560
|
_normalizeCopyImageDataOptions(options_) {
|
|
1994
|
-
const {
|
|
1995
|
-
const options = {
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
}
|
|
2000
|
-
options.bytesPerRow = options_.bytesPerRow || width * (info.bytesPerPixel || 4);
|
|
2001
|
-
options.rowsPerImage = options_.rowsPerImage || height;
|
|
2002
|
-
return options;
|
|
2561
|
+
const { data, depth, ...writeOptions } = options_;
|
|
2562
|
+
const options = this._normalizeTextureWriteOptions({
|
|
2563
|
+
...writeOptions,
|
|
2564
|
+
depthOrArrayLayers: writeOptions.depthOrArrayLayers ?? depth
|
|
2565
|
+
});
|
|
2566
|
+
return { data, depth: options.depthOrArrayLayers, ...options };
|
|
2003
2567
|
}
|
|
2004
2568
|
_normalizeCopyExternalImageOptions(options_) {
|
|
2569
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2570
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2571
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
2005
2572
|
const size = this.device.getExternalImageSize(options_.image);
|
|
2006
|
-
const options = {
|
|
2007
|
-
|
|
2008
|
-
|
|
2573
|
+
const options = {
|
|
2574
|
+
..._Texture.defaultCopyExternalImageOptions,
|
|
2575
|
+
...mipLevelSize,
|
|
2576
|
+
...size,
|
|
2577
|
+
...optionsWithoutUndefined
|
|
2578
|
+
};
|
|
2579
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2580
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2581
|
+
options.depth = Math.min(options.depth, mipLevelSize.depthOrArrayLayers - options.z);
|
|
2009
2582
|
return options;
|
|
2010
2583
|
}
|
|
2011
2584
|
_normalizeTextureReadOptions(options_) {
|
|
2012
|
-
const
|
|
2013
|
-
const
|
|
2014
|
-
|
|
2015
|
-
options
|
|
2585
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2586
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2587
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
2588
|
+
const options = {
|
|
2589
|
+
..._Texture.defaultTextureReadOptions,
|
|
2590
|
+
...mipLevelSize,
|
|
2591
|
+
...optionsWithoutUndefined
|
|
2592
|
+
};
|
|
2593
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2594
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2595
|
+
options.depthOrArrayLayers = Math.min(options.depthOrArrayLayers, mipLevelSize.depthOrArrayLayers - options.z);
|
|
2016
2596
|
return options;
|
|
2017
2597
|
}
|
|
2598
|
+
/**
|
|
2599
|
+
* Normalizes a texture read request and validates the color-only readback contract used by the
|
|
2600
|
+
* current texture read APIs. Supported dimensions are `2d`, `cube`, `cube-array`,
|
|
2601
|
+
* `2d-array`, and `3d`.
|
|
2602
|
+
*
|
|
2603
|
+
* @throws if the texture format, aspect, or dimension is not supported by the first-pass
|
|
2604
|
+
* color-read implementation.
|
|
2605
|
+
*/
|
|
2606
|
+
_getSupportedColorReadOptions(options_) {
|
|
2607
|
+
const options = this._normalizeTextureReadOptions(options_);
|
|
2608
|
+
const formatInfo = textureFormatDecoder.getInfo(this.format);
|
|
2609
|
+
this._validateColorReadAspect(options);
|
|
2610
|
+
this._validateColorReadFormat(formatInfo);
|
|
2611
|
+
switch (this.dimension) {
|
|
2612
|
+
case "2d":
|
|
2613
|
+
case "cube":
|
|
2614
|
+
case "cube-array":
|
|
2615
|
+
case "2d-array":
|
|
2616
|
+
case "3d":
|
|
2617
|
+
return options;
|
|
2618
|
+
default:
|
|
2619
|
+
throw new Error(`${this} color readback does not support ${this.dimension} textures`);
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
/** Validates that a read request targets the full color aspect of the texture. */
|
|
2623
|
+
_validateColorReadAspect(options) {
|
|
2624
|
+
if (options.aspect !== "all") {
|
|
2625
|
+
throw new Error(`${this} color readback only supports aspect 'all'`);
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
/** Validates that a read request targets an uncompressed color-renderable texture format. */
|
|
2629
|
+
_validateColorReadFormat(formatInfo) {
|
|
2630
|
+
if (formatInfo.compressed) {
|
|
2631
|
+
throw new Error(`${this} color readback does not support compressed formats (${this.format})`);
|
|
2632
|
+
}
|
|
2633
|
+
switch (formatInfo.attachment) {
|
|
2634
|
+
case "color":
|
|
2635
|
+
return;
|
|
2636
|
+
case "depth":
|
|
2637
|
+
throw new Error(`${this} color readback does not support depth formats (${this.format})`);
|
|
2638
|
+
case "stencil":
|
|
2639
|
+
throw new Error(`${this} color readback does not support stencil formats (${this.format})`);
|
|
2640
|
+
case "depth-stencil":
|
|
2641
|
+
throw new Error(`${this} color readback does not support depth-stencil formats (${this.format})`);
|
|
2642
|
+
default:
|
|
2643
|
+
throw new Error(`${this} color readback does not support format ${this.format}`);
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2018
2646
|
_normalizeTextureWriteOptions(options_) {
|
|
2019
|
-
const
|
|
2020
|
-
const
|
|
2021
|
-
|
|
2022
|
-
options
|
|
2647
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2648
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2649
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
2650
|
+
const options = {
|
|
2651
|
+
..._Texture.defaultTextureWriteOptions,
|
|
2652
|
+
...mipLevelSize,
|
|
2653
|
+
...optionsWithoutUndefined
|
|
2654
|
+
};
|
|
2655
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2656
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2657
|
+
options.depthOrArrayLayers = Math.min(options.depthOrArrayLayers, mipLevelSize.depthOrArrayLayers - options.z);
|
|
2658
|
+
const layout = textureFormatDecoder.computeMemoryLayout({
|
|
2659
|
+
format: this.format,
|
|
2660
|
+
width: options.width,
|
|
2661
|
+
height: options.height,
|
|
2662
|
+
depth: options.depthOrArrayLayers,
|
|
2663
|
+
byteAlignment: this.byteAlignment
|
|
2664
|
+
});
|
|
2665
|
+
const minimumBytesPerRow = layout.bytesPerPixel * options.width;
|
|
2666
|
+
options.bytesPerRow = optionsWithoutUndefined.bytesPerRow ?? layout.bytesPerRow;
|
|
2667
|
+
options.rowsPerImage = optionsWithoutUndefined.rowsPerImage ?? options.height;
|
|
2668
|
+
if (options.bytesPerRow < minimumBytesPerRow) {
|
|
2669
|
+
throw new Error(`bytesPerRow (${options.bytesPerRow}) must be at least ${minimumBytesPerRow} for ${this.format}`);
|
|
2670
|
+
}
|
|
2671
|
+
if (options.rowsPerImage < options.height) {
|
|
2672
|
+
throw new Error(`rowsPerImage (${options.rowsPerImage}) must be at least ${options.height} for ${this.format}`);
|
|
2673
|
+
}
|
|
2674
|
+
const bytesPerPixel = this.device.getTextureFormatInfo(this.format).bytesPerPixel;
|
|
2675
|
+
if (bytesPerPixel && options.bytesPerRow % bytesPerPixel !== 0) {
|
|
2676
|
+
throw new Error(`bytesPerRow (${options.bytesPerRow}) must be a multiple of bytesPerPixel (${bytesPerPixel}) for ${this.format}`);
|
|
2677
|
+
}
|
|
2023
2678
|
return options;
|
|
2024
2679
|
}
|
|
2680
|
+
_getMipLevelSize(mipLevel) {
|
|
2681
|
+
const width = Math.max(1, this.width >> mipLevel);
|
|
2682
|
+
const height = this.baseDimension === "1d" ? 1 : Math.max(1, this.height >> mipLevel);
|
|
2683
|
+
const depthOrArrayLayers = this.dimension === "3d" ? Math.max(1, this.depth >> mipLevel) : this.depth;
|
|
2684
|
+
return { width, height, depthOrArrayLayers };
|
|
2685
|
+
}
|
|
2686
|
+
getAllocatedByteLength() {
|
|
2687
|
+
let allocatedByteLength = 0;
|
|
2688
|
+
for (let mipLevel = 0; mipLevel < this.mipLevels; mipLevel++) {
|
|
2689
|
+
const { width, height, depthOrArrayLayers } = this._getMipLevelSize(mipLevel);
|
|
2690
|
+
allocatedByteLength += textureFormatDecoder.computeMemoryLayout({
|
|
2691
|
+
format: this.format,
|
|
2692
|
+
width,
|
|
2693
|
+
height,
|
|
2694
|
+
depth: depthOrArrayLayers,
|
|
2695
|
+
byteAlignment: 1
|
|
2696
|
+
}).byteLength;
|
|
2697
|
+
}
|
|
2698
|
+
return allocatedByteLength * this.samples;
|
|
2699
|
+
}
|
|
2700
|
+
static _omitUndefined(options) {
|
|
2701
|
+
return Object.fromEntries(Object.entries(options).filter(([, value]) => value !== void 0));
|
|
2702
|
+
}
|
|
2025
2703
|
};
|
|
2026
2704
|
var Texture = _Texture;
|
|
2027
2705
|
/** The texture can be bound for use as a sampled texture in a shader */
|
|
@@ -2057,6 +2735,10 @@ __publicField(Texture, "defaultCopyDataOptions", {
|
|
|
2057
2735
|
byteOffset: 0,
|
|
2058
2736
|
bytesPerRow: void 0,
|
|
2059
2737
|
rowsPerImage: void 0,
|
|
2738
|
+
width: void 0,
|
|
2739
|
+
height: void 0,
|
|
2740
|
+
depthOrArrayLayers: void 0,
|
|
2741
|
+
depth: 1,
|
|
2060
2742
|
mipLevel: 0,
|
|
2061
2743
|
x: 0,
|
|
2062
2744
|
y: 0,
|
|
@@ -2090,6 +2772,19 @@ __publicField(Texture, "defaultTextureReadOptions", {
|
|
|
2090
2772
|
mipLevel: 0,
|
|
2091
2773
|
aspect: "all"
|
|
2092
2774
|
});
|
|
2775
|
+
__publicField(Texture, "defaultTextureWriteOptions", {
|
|
2776
|
+
byteOffset: 0,
|
|
2777
|
+
bytesPerRow: void 0,
|
|
2778
|
+
rowsPerImage: void 0,
|
|
2779
|
+
x: 0,
|
|
2780
|
+
y: 0,
|
|
2781
|
+
z: 0,
|
|
2782
|
+
width: void 0,
|
|
2783
|
+
height: void 0,
|
|
2784
|
+
depthOrArrayLayers: 1,
|
|
2785
|
+
mipLevel: 0,
|
|
2786
|
+
aspect: "all"
|
|
2787
|
+
});
|
|
2093
2788
|
|
|
2094
2789
|
// dist/adapter/resources/texture-view.js
|
|
2095
2790
|
var _TextureView = class extends Resource {
|
|
@@ -2466,10 +3161,23 @@ var _RenderPipeline = class extends Resource {
|
|
|
2466
3161
|
linkStatus = "pending";
|
|
2467
3162
|
/** The hash of the pipeline */
|
|
2468
3163
|
hash = "";
|
|
3164
|
+
/** Optional shared backend implementation */
|
|
3165
|
+
sharedRenderPipeline = null;
|
|
3166
|
+
/** Whether shader or pipeline compilation/linking is still in progress */
|
|
3167
|
+
get isPending() {
|
|
3168
|
+
var _a;
|
|
3169
|
+
return this.linkStatus === "pending" || this.vs.compilationStatus === "pending" || ((_a = this.fs) == null ? void 0 : _a.compilationStatus) === "pending";
|
|
3170
|
+
}
|
|
3171
|
+
/** Whether shader or pipeline compilation/linking has failed */
|
|
3172
|
+
get isErrored() {
|
|
3173
|
+
var _a;
|
|
3174
|
+
return this.linkStatus === "error" || this.vs.compilationStatus === "error" || ((_a = this.fs) == null ? void 0 : _a.compilationStatus) === "error";
|
|
3175
|
+
}
|
|
2469
3176
|
constructor(device, props) {
|
|
2470
3177
|
super(device, props, _RenderPipeline.defaultProps);
|
|
2471
3178
|
this.shaderLayout = this.props.shaderLayout;
|
|
2472
3179
|
this.bufferLayout = this.props.bufferLayout || [];
|
|
3180
|
+
this.sharedRenderPipeline = this.props._sharedRenderPipeline || null;
|
|
2473
3181
|
}
|
|
2474
3182
|
};
|
|
2475
3183
|
var RenderPipeline = _RenderPipeline;
|
|
@@ -2487,10 +3195,476 @@ __publicField(RenderPipeline, "defaultProps", {
|
|
|
2487
3195
|
colorAttachmentFormats: void 0,
|
|
2488
3196
|
depthStencilAttachmentFormat: void 0,
|
|
2489
3197
|
parameters: {},
|
|
2490
|
-
|
|
2491
|
-
|
|
3198
|
+
varyings: void 0,
|
|
3199
|
+
bufferMode: void 0,
|
|
3200
|
+
disableWarnings: false,
|
|
3201
|
+
_sharedRenderPipeline: void 0,
|
|
3202
|
+
bindings: void 0,
|
|
3203
|
+
bindGroups: void 0
|
|
2492
3204
|
});
|
|
2493
3205
|
|
|
3206
|
+
// dist/adapter/resources/shared-render-pipeline.js
|
|
3207
|
+
var SharedRenderPipeline = class extends Resource {
|
|
3208
|
+
get [Symbol.toStringTag]() {
|
|
3209
|
+
return "SharedRenderPipeline";
|
|
3210
|
+
}
|
|
3211
|
+
constructor(device, props) {
|
|
3212
|
+
super(device, props, {
|
|
3213
|
+
...Resource.defaultProps,
|
|
3214
|
+
handle: void 0,
|
|
3215
|
+
vs: void 0,
|
|
3216
|
+
fs: void 0,
|
|
3217
|
+
varyings: void 0,
|
|
3218
|
+
bufferMode: void 0
|
|
3219
|
+
});
|
|
3220
|
+
}
|
|
3221
|
+
};
|
|
3222
|
+
|
|
3223
|
+
// dist/adapter/resources/compute-pipeline.js
|
|
3224
|
+
var _ComputePipeline = class extends Resource {
|
|
3225
|
+
get [Symbol.toStringTag]() {
|
|
3226
|
+
return "ComputePipeline";
|
|
3227
|
+
}
|
|
3228
|
+
hash = "";
|
|
3229
|
+
/** The merged shader layout */
|
|
3230
|
+
shaderLayout;
|
|
3231
|
+
constructor(device, props) {
|
|
3232
|
+
super(device, props, _ComputePipeline.defaultProps);
|
|
3233
|
+
this.shaderLayout = props.shaderLayout;
|
|
3234
|
+
}
|
|
3235
|
+
};
|
|
3236
|
+
var ComputePipeline = _ComputePipeline;
|
|
3237
|
+
__publicField(ComputePipeline, "defaultProps", {
|
|
3238
|
+
...Resource.defaultProps,
|
|
3239
|
+
shader: void 0,
|
|
3240
|
+
entryPoint: void 0,
|
|
3241
|
+
constants: {},
|
|
3242
|
+
shaderLayout: void 0
|
|
3243
|
+
});
|
|
3244
|
+
|
|
3245
|
+
// dist/factories/pipeline-factory.js
|
|
3246
|
+
var _PipelineFactory = class {
|
|
3247
|
+
/** Get the singleton default pipeline factory for the specified device */
|
|
3248
|
+
static getDefaultPipelineFactory(device) {
|
|
3249
|
+
const moduleData = device.getModuleData("@luma.gl/core");
|
|
3250
|
+
moduleData.defaultPipelineFactory ||= new _PipelineFactory(device);
|
|
3251
|
+
return moduleData.defaultPipelineFactory;
|
|
3252
|
+
}
|
|
3253
|
+
device;
|
|
3254
|
+
_hashCounter = 0;
|
|
3255
|
+
_hashes = {};
|
|
3256
|
+
_renderPipelineCache = {};
|
|
3257
|
+
_computePipelineCache = {};
|
|
3258
|
+
_sharedRenderPipelineCache = {};
|
|
3259
|
+
get [Symbol.toStringTag]() {
|
|
3260
|
+
return "PipelineFactory";
|
|
3261
|
+
}
|
|
3262
|
+
toString() {
|
|
3263
|
+
return `PipelineFactory(${this.device.id})`;
|
|
3264
|
+
}
|
|
3265
|
+
constructor(device) {
|
|
3266
|
+
this.device = device;
|
|
3267
|
+
}
|
|
3268
|
+
/**
|
|
3269
|
+
* WebGL has two cache layers with different priorities:
|
|
3270
|
+
* - `_sharedRenderPipelineCache` owns `WEBGLSharedRenderPipeline` / `WebGLProgram` reuse.
|
|
3271
|
+
* - `_renderPipelineCache` owns `RenderPipeline` wrapper reuse.
|
|
3272
|
+
*
|
|
3273
|
+
* Shared WebGL program reuse is the hard requirement. Wrapper reuse is beneficial,
|
|
3274
|
+
* but wrapper cache misses are acceptable if that keeps the cache logic simple and
|
|
3275
|
+
* prevents incorrect cache hits.
|
|
3276
|
+
*
|
|
3277
|
+
* In particular, wrapper hash logic must never force program creation or linked-program
|
|
3278
|
+
* introspection just to decide whether a shared WebGL program can be reused.
|
|
3279
|
+
*/
|
|
3280
|
+
/** Return a RenderPipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
3281
|
+
createRenderPipeline(props) {
|
|
3282
|
+
var _a;
|
|
3283
|
+
if (!this.device.props._cachePipelines) {
|
|
3284
|
+
return this.device.createRenderPipeline(props);
|
|
3285
|
+
}
|
|
3286
|
+
const allProps = { ...RenderPipeline.defaultProps, ...props };
|
|
3287
|
+
const cache = this._renderPipelineCache;
|
|
3288
|
+
const hash = this._hashRenderPipeline(allProps);
|
|
3289
|
+
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.resource;
|
|
3290
|
+
if (!pipeline) {
|
|
3291
|
+
const sharedRenderPipeline = this.device.type === "webgl" && this.device.props._sharePipelines ? this.createSharedRenderPipeline(allProps) : void 0;
|
|
3292
|
+
pipeline = this.device.createRenderPipeline({
|
|
3293
|
+
...allProps,
|
|
3294
|
+
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached"),
|
|
3295
|
+
_sharedRenderPipeline: sharedRenderPipeline
|
|
3296
|
+
});
|
|
3297
|
+
pipeline.hash = hash;
|
|
3298
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
3299
|
+
if (this.device.props.debugFactories) {
|
|
3300
|
+
log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
3301
|
+
}
|
|
3302
|
+
} else {
|
|
3303
|
+
cache[hash].useCount++;
|
|
3304
|
+
if (this.device.props.debugFactories) {
|
|
3305
|
+
log.log(3, `${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
return pipeline;
|
|
3309
|
+
}
|
|
3310
|
+
/** Return a ComputePipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
3311
|
+
createComputePipeline(props) {
|
|
3312
|
+
var _a;
|
|
3313
|
+
if (!this.device.props._cachePipelines) {
|
|
3314
|
+
return this.device.createComputePipeline(props);
|
|
3315
|
+
}
|
|
3316
|
+
const allProps = { ...ComputePipeline.defaultProps, ...props };
|
|
3317
|
+
const cache = this._computePipelineCache;
|
|
3318
|
+
const hash = this._hashComputePipeline(allProps);
|
|
3319
|
+
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.resource;
|
|
3320
|
+
if (!pipeline) {
|
|
3321
|
+
pipeline = this.device.createComputePipeline({
|
|
3322
|
+
...allProps,
|
|
3323
|
+
id: allProps.id ? `${allProps.id}-cached` : void 0
|
|
3324
|
+
});
|
|
3325
|
+
pipeline.hash = hash;
|
|
3326
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
3327
|
+
if (this.device.props.debugFactories) {
|
|
3328
|
+
log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
3329
|
+
}
|
|
3330
|
+
} else {
|
|
3331
|
+
cache[hash].useCount++;
|
|
3332
|
+
if (this.device.props.debugFactories) {
|
|
3333
|
+
log.log(3, `${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
return pipeline;
|
|
3337
|
+
}
|
|
3338
|
+
release(pipeline) {
|
|
3339
|
+
if (!this.device.props._cachePipelines) {
|
|
3340
|
+
pipeline.destroy();
|
|
3341
|
+
return;
|
|
3342
|
+
}
|
|
3343
|
+
const cache = this._getCache(pipeline);
|
|
3344
|
+
const hash = pipeline.hash;
|
|
3345
|
+
cache[hash].useCount--;
|
|
3346
|
+
if (cache[hash].useCount === 0) {
|
|
3347
|
+
this._destroyPipeline(pipeline);
|
|
3348
|
+
if (this.device.props.debugFactories) {
|
|
3349
|
+
log.log(3, `${this}: ${pipeline} released and destroyed`)();
|
|
3350
|
+
}
|
|
3351
|
+
} else if (cache[hash].useCount < 0) {
|
|
3352
|
+
log.error(`${this}: ${pipeline} released, useCount < 0, resetting`)();
|
|
3353
|
+
cache[hash].useCount = 0;
|
|
3354
|
+
} else if (this.device.props.debugFactories) {
|
|
3355
|
+
log.log(3, `${this}: ${pipeline} released, count=${cache[hash].useCount}`)();
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
3358
|
+
createSharedRenderPipeline(props) {
|
|
3359
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(props);
|
|
3360
|
+
let sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
3361
|
+
if (!sharedCacheItem) {
|
|
3362
|
+
const sharedRenderPipeline = this.device._createSharedRenderPipelineWebGL(props);
|
|
3363
|
+
sharedCacheItem = { resource: sharedRenderPipeline, useCount: 0 };
|
|
3364
|
+
this._sharedRenderPipelineCache[sharedPipelineHash] = sharedCacheItem;
|
|
3365
|
+
}
|
|
3366
|
+
sharedCacheItem.useCount++;
|
|
3367
|
+
return sharedCacheItem.resource;
|
|
3368
|
+
}
|
|
3369
|
+
releaseSharedRenderPipeline(pipeline) {
|
|
3370
|
+
if (!pipeline.sharedRenderPipeline) {
|
|
3371
|
+
return;
|
|
3372
|
+
}
|
|
3373
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(pipeline.sharedRenderPipeline.props);
|
|
3374
|
+
const sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
3375
|
+
if (!sharedCacheItem) {
|
|
3376
|
+
return;
|
|
3377
|
+
}
|
|
3378
|
+
sharedCacheItem.useCount--;
|
|
3379
|
+
if (sharedCacheItem.useCount === 0) {
|
|
3380
|
+
sharedCacheItem.resource.destroy();
|
|
3381
|
+
delete this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
// PRIVATE
|
|
3385
|
+
/** Destroy a cached pipeline, removing it from the cache if configured to do so. */
|
|
3386
|
+
_destroyPipeline(pipeline) {
|
|
3387
|
+
const cache = this._getCache(pipeline);
|
|
3388
|
+
if (!this.device.props._destroyPipelines) {
|
|
3389
|
+
return false;
|
|
3390
|
+
}
|
|
3391
|
+
delete cache[pipeline.hash];
|
|
3392
|
+
pipeline.destroy();
|
|
3393
|
+
if (pipeline instanceof RenderPipeline) {
|
|
3394
|
+
this.releaseSharedRenderPipeline(pipeline);
|
|
3395
|
+
}
|
|
3396
|
+
return true;
|
|
3397
|
+
}
|
|
3398
|
+
/** Get the appropriate cache for the type of pipeline */
|
|
3399
|
+
_getCache(pipeline) {
|
|
3400
|
+
let cache;
|
|
3401
|
+
if (pipeline instanceof ComputePipeline) {
|
|
3402
|
+
cache = this._computePipelineCache;
|
|
3403
|
+
}
|
|
3404
|
+
if (pipeline instanceof RenderPipeline) {
|
|
3405
|
+
cache = this._renderPipelineCache;
|
|
3406
|
+
}
|
|
3407
|
+
if (!cache) {
|
|
3408
|
+
throw new Error(`${this}`);
|
|
3409
|
+
}
|
|
3410
|
+
if (!cache[pipeline.hash]) {
|
|
3411
|
+
throw new Error(`${this}: ${pipeline} matched incorrect entry`);
|
|
3412
|
+
}
|
|
3413
|
+
return cache;
|
|
3414
|
+
}
|
|
3415
|
+
/** Calculate a hash based on all the inputs for a compute pipeline */
|
|
3416
|
+
_hashComputePipeline(props) {
|
|
3417
|
+
const { type } = this.device;
|
|
3418
|
+
const shaderHash = this._getHash(props.shader.source);
|
|
3419
|
+
const shaderLayoutHash = this._getHash(JSON.stringify(props.shaderLayout));
|
|
3420
|
+
return `${type}/C/${shaderHash}SL${shaderLayoutHash}`;
|
|
3421
|
+
}
|
|
3422
|
+
/** Calculate a hash based on all the inputs for a render pipeline */
|
|
3423
|
+
_hashRenderPipeline(props) {
|
|
3424
|
+
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
3425
|
+
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
3426
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
3427
|
+
const shaderLayoutHash = this._getHash(JSON.stringify(props.shaderLayout));
|
|
3428
|
+
const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
|
|
3429
|
+
const { type } = this.device;
|
|
3430
|
+
switch (type) {
|
|
3431
|
+
case "webgl":
|
|
3432
|
+
const webglParameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
3433
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${webglParameterHash}SL${shaderLayoutHash}BL${bufferLayoutHash}`;
|
|
3434
|
+
case "webgpu":
|
|
3435
|
+
default:
|
|
3436
|
+
const entryPointHash = this._getHash(JSON.stringify({
|
|
3437
|
+
vertexEntryPoint: props.vertexEntryPoint,
|
|
3438
|
+
fragmentEntryPoint: props.fragmentEntryPoint
|
|
3439
|
+
}));
|
|
3440
|
+
const parameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
3441
|
+
const attachmentHash = this._getWebGPUAttachmentHash(props);
|
|
3442
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}EP${entryPointHash}P${parameterHash}SL${shaderLayoutHash}BL${bufferLayoutHash}A${attachmentHash}`;
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3445
|
+
// This is the only gate for shared `WebGLProgram` reuse.
|
|
3446
|
+
// Only include inputs that affect program linking or transform-feedback linkage.
|
|
3447
|
+
// Wrapper-only concerns such as topology, parameters, attachment formats and layout
|
|
3448
|
+
// overrides must not be added here.
|
|
3449
|
+
_hashSharedRenderPipeline(props) {
|
|
3450
|
+
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
3451
|
+
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
3452
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
3453
|
+
return `webgl/S/${vsHash}/${fsHash}V${varyingHash}`;
|
|
3454
|
+
}
|
|
3455
|
+
_getHash(key) {
|
|
3456
|
+
if (this._hashes[key] === void 0) {
|
|
3457
|
+
this._hashes[key] = this._hashCounter++;
|
|
3458
|
+
}
|
|
3459
|
+
return this._hashes[key];
|
|
3460
|
+
}
|
|
3461
|
+
_getWebGLVaryingHash(props) {
|
|
3462
|
+
const { varyings = [], bufferMode = null } = props;
|
|
3463
|
+
return this._getHash(JSON.stringify({ varyings, bufferMode }));
|
|
3464
|
+
}
|
|
3465
|
+
_getWebGPUAttachmentHash(props) {
|
|
3466
|
+
var _a;
|
|
3467
|
+
const colorAttachmentFormats = props.colorAttachmentFormats ?? [
|
|
3468
|
+
this.device.preferredColorFormat
|
|
3469
|
+
];
|
|
3470
|
+
const depthStencilAttachmentFormat = ((_a = props.parameters) == null ? void 0 : _a.depthWriteEnabled) ? props.depthStencilAttachmentFormat || this.device.preferredDepthFormat : null;
|
|
3471
|
+
return this._getHash(JSON.stringify({
|
|
3472
|
+
colorAttachmentFormats,
|
|
3473
|
+
depthStencilAttachmentFormat
|
|
3474
|
+
}));
|
|
3475
|
+
}
|
|
3476
|
+
};
|
|
3477
|
+
var PipelineFactory = _PipelineFactory;
|
|
3478
|
+
__publicField(PipelineFactory, "defaultProps", { ...RenderPipeline.defaultProps });
|
|
3479
|
+
|
|
3480
|
+
// dist/factories/shader-factory.js
|
|
3481
|
+
var _ShaderFactory = class {
|
|
3482
|
+
/** Returns the default ShaderFactory for the given {@link Device}, creating one if necessary. */
|
|
3483
|
+
static getDefaultShaderFactory(device) {
|
|
3484
|
+
const moduleData = device.getModuleData("@luma.gl/core");
|
|
3485
|
+
moduleData.defaultShaderFactory ||= new _ShaderFactory(device);
|
|
3486
|
+
return moduleData.defaultShaderFactory;
|
|
3487
|
+
}
|
|
3488
|
+
device;
|
|
3489
|
+
_cache = {};
|
|
3490
|
+
get [Symbol.toStringTag]() {
|
|
3491
|
+
return "ShaderFactory";
|
|
3492
|
+
}
|
|
3493
|
+
toString() {
|
|
3494
|
+
return `${this[Symbol.toStringTag]}(${this.device.id})`;
|
|
3495
|
+
}
|
|
3496
|
+
/** @internal */
|
|
3497
|
+
constructor(device) {
|
|
3498
|
+
this.device = device;
|
|
3499
|
+
}
|
|
3500
|
+
/** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
|
|
3501
|
+
createShader(props) {
|
|
3502
|
+
if (!this.device.props._cacheShaders) {
|
|
3503
|
+
return this.device.createShader(props);
|
|
3504
|
+
}
|
|
3505
|
+
const key = this._hashShader(props);
|
|
3506
|
+
let cacheEntry = this._cache[key];
|
|
3507
|
+
if (!cacheEntry) {
|
|
3508
|
+
const resource = this.device.createShader({
|
|
3509
|
+
...props,
|
|
3510
|
+
id: props.id ? `${props.id}-cached` : void 0
|
|
3511
|
+
});
|
|
3512
|
+
this._cache[key] = cacheEntry = { resource, useCount: 1 };
|
|
3513
|
+
if (this.device.props.debugFactories) {
|
|
3514
|
+
log.log(3, `${this}: Created new shader ${resource.id}`)();
|
|
3515
|
+
}
|
|
3516
|
+
} else {
|
|
3517
|
+
cacheEntry.useCount++;
|
|
3518
|
+
if (this.device.props.debugFactories) {
|
|
3519
|
+
log.log(3, `${this}: Reusing shader ${cacheEntry.resource.id} count=${cacheEntry.useCount}`)();
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
return cacheEntry.resource;
|
|
3523
|
+
}
|
|
3524
|
+
/** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
|
|
3525
|
+
release(shader) {
|
|
3526
|
+
if (!this.device.props._cacheShaders) {
|
|
3527
|
+
shader.destroy();
|
|
3528
|
+
return;
|
|
3529
|
+
}
|
|
3530
|
+
const key = this._hashShader(shader);
|
|
3531
|
+
const cacheEntry = this._cache[key];
|
|
3532
|
+
if (cacheEntry) {
|
|
3533
|
+
cacheEntry.useCount--;
|
|
3534
|
+
if (cacheEntry.useCount === 0) {
|
|
3535
|
+
if (this.device.props._destroyShaders) {
|
|
3536
|
+
delete this._cache[key];
|
|
3537
|
+
cacheEntry.resource.destroy();
|
|
3538
|
+
if (this.device.props.debugFactories) {
|
|
3539
|
+
log.log(3, `${this}: Releasing shader ${shader.id}, destroyed`)();
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
} else if (cacheEntry.useCount < 0) {
|
|
3543
|
+
throw new Error(`ShaderFactory: Shader ${shader.id} released too many times`);
|
|
3544
|
+
} else if (this.device.props.debugFactories) {
|
|
3545
|
+
log.log(3, `${this}: Releasing shader ${shader.id} count=${cacheEntry.useCount}`)();
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3548
|
+
}
|
|
3549
|
+
// PRIVATE
|
|
3550
|
+
_hashShader(value) {
|
|
3551
|
+
return `${value.stage}:${value.source}`;
|
|
3552
|
+
}
|
|
3553
|
+
};
|
|
3554
|
+
var ShaderFactory = _ShaderFactory;
|
|
3555
|
+
__publicField(ShaderFactory, "defaultProps", { ...Shader.defaultProps });
|
|
3556
|
+
|
|
3557
|
+
// dist/adapter-utils/bind-groups.js
|
|
3558
|
+
function getShaderLayoutBinding(shaderLayout, bindingName, options) {
|
|
3559
|
+
const bindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName || `${binding.name.toLocaleLowerCase()}uniforms` === bindingName.toLocaleLowerCase());
|
|
3560
|
+
if (!bindingLayout && !(options == null ? void 0 : options.ignoreWarnings)) {
|
|
3561
|
+
log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
|
|
3562
|
+
}
|
|
3563
|
+
return bindingLayout || null;
|
|
3564
|
+
}
|
|
3565
|
+
function normalizeBindingsByGroup(shaderLayout, bindingsOrBindGroups) {
|
|
3566
|
+
if (!bindingsOrBindGroups) {
|
|
3567
|
+
return {};
|
|
3568
|
+
}
|
|
3569
|
+
if (areBindingsGrouped(bindingsOrBindGroups)) {
|
|
3570
|
+
const bindGroups2 = bindingsOrBindGroups;
|
|
3571
|
+
return Object.fromEntries(Object.entries(bindGroups2).map(([group, bindings]) => [Number(group), { ...bindings }]));
|
|
3572
|
+
}
|
|
3573
|
+
const bindGroups = {};
|
|
3574
|
+
for (const [bindingName, binding] of Object.entries(bindingsOrBindGroups)) {
|
|
3575
|
+
const bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);
|
|
3576
|
+
const group = (bindingLayout == null ? void 0 : bindingLayout.group) ?? 0;
|
|
3577
|
+
bindGroups[group] ||= {};
|
|
3578
|
+
bindGroups[group][bindingName] = binding;
|
|
3579
|
+
}
|
|
3580
|
+
return bindGroups;
|
|
3581
|
+
}
|
|
3582
|
+
function flattenBindingsByGroup(bindGroups) {
|
|
3583
|
+
const bindings = {};
|
|
3584
|
+
for (const groupBindings of Object.values(bindGroups)) {
|
|
3585
|
+
Object.assign(bindings, groupBindings);
|
|
3586
|
+
}
|
|
3587
|
+
return bindings;
|
|
3588
|
+
}
|
|
3589
|
+
function areBindingsGrouped(bindingsOrBindGroups) {
|
|
3590
|
+
const keys = Object.keys(bindingsOrBindGroups);
|
|
3591
|
+
return keys.length > 0 && keys.every((key) => /^\d+$/.test(key));
|
|
3592
|
+
}
|
|
3593
|
+
|
|
3594
|
+
// dist/factories/bind-group-factory.js
|
|
3595
|
+
var BindGroupFactory = class {
|
|
3596
|
+
device;
|
|
3597
|
+
_layoutCacheByPipeline = /* @__PURE__ */ new WeakMap();
|
|
3598
|
+
_bindGroupCacheByLayout = /* @__PURE__ */ new WeakMap();
|
|
3599
|
+
constructor(device) {
|
|
3600
|
+
this.device = device;
|
|
3601
|
+
}
|
|
3602
|
+
getBindGroups(pipeline, bindings, bindGroupCacheKeys) {
|
|
3603
|
+
if (this.device.type !== "webgpu" || pipeline.shaderLayout.bindings.length === 0) {
|
|
3604
|
+
return {};
|
|
3605
|
+
}
|
|
3606
|
+
const bindingsByGroup = normalizeBindingsByGroup(pipeline.shaderLayout, bindings);
|
|
3607
|
+
const resolvedBindGroups = {};
|
|
3608
|
+
for (const group of getBindGroupIndicesUpToMax(pipeline.shaderLayout.bindings)) {
|
|
3609
|
+
const groupBindings = bindingsByGroup[group];
|
|
3610
|
+
const bindGroupLayout = this._getBindGroupLayout(pipeline, group);
|
|
3611
|
+
if (!groupBindings || Object.keys(groupBindings).length === 0) {
|
|
3612
|
+
if (!hasBindingsInGroup(pipeline.shaderLayout.bindings, group)) {
|
|
3613
|
+
resolvedBindGroups[group] = this._getEmptyBindGroup(bindGroupLayout, pipeline.shaderLayout, group);
|
|
3614
|
+
}
|
|
3615
|
+
continue;
|
|
3616
|
+
}
|
|
3617
|
+
const bindGroupCacheKey = bindGroupCacheKeys == null ? void 0 : bindGroupCacheKeys[group];
|
|
3618
|
+
if (bindGroupCacheKey) {
|
|
3619
|
+
const layoutCache = this._getLayoutBindGroupCache(bindGroupLayout);
|
|
3620
|
+
if (layoutCache.bindGroupsBySource.has(bindGroupCacheKey)) {
|
|
3621
|
+
resolvedBindGroups[group] = layoutCache.bindGroupsBySource.get(bindGroupCacheKey) || null;
|
|
3622
|
+
continue;
|
|
3623
|
+
}
|
|
3624
|
+
const bindGroup = this.device._createBindGroupWebGPU(bindGroupLayout, pipeline.shaderLayout, groupBindings, group);
|
|
3625
|
+
layoutCache.bindGroupsBySource.set(bindGroupCacheKey, bindGroup);
|
|
3626
|
+
resolvedBindGroups[group] = bindGroup;
|
|
3627
|
+
} else {
|
|
3628
|
+
resolvedBindGroups[group] = this.device._createBindGroupWebGPU(bindGroupLayout, pipeline.shaderLayout, groupBindings, group);
|
|
3629
|
+
}
|
|
3630
|
+
}
|
|
3631
|
+
return resolvedBindGroups;
|
|
3632
|
+
}
|
|
3633
|
+
_getBindGroupLayout(pipeline, group) {
|
|
3634
|
+
let layoutCache = this._layoutCacheByPipeline.get(pipeline);
|
|
3635
|
+
if (!layoutCache) {
|
|
3636
|
+
layoutCache = {};
|
|
3637
|
+
this._layoutCacheByPipeline.set(pipeline, layoutCache);
|
|
3638
|
+
}
|
|
3639
|
+
layoutCache[group] ||= this.device._createBindGroupLayoutWebGPU(pipeline, group);
|
|
3640
|
+
return layoutCache[group];
|
|
3641
|
+
}
|
|
3642
|
+
_getEmptyBindGroup(bindGroupLayout, shaderLayout, group) {
|
|
3643
|
+
const layoutCache = this._getLayoutBindGroupCache(bindGroupLayout);
|
|
3644
|
+
layoutCache.emptyBindGroup ||= this.device._createBindGroupWebGPU(bindGroupLayout, shaderLayout, {}, group) || null;
|
|
3645
|
+
return layoutCache.emptyBindGroup;
|
|
3646
|
+
}
|
|
3647
|
+
_getLayoutBindGroupCache(bindGroupLayout) {
|
|
3648
|
+
let layoutCache = this._bindGroupCacheByLayout.get(bindGroupLayout);
|
|
3649
|
+
if (!layoutCache) {
|
|
3650
|
+
layoutCache = { bindGroupsBySource: /* @__PURE__ */ new WeakMap() };
|
|
3651
|
+
this._bindGroupCacheByLayout.set(bindGroupLayout, layoutCache);
|
|
3652
|
+
}
|
|
3653
|
+
return layoutCache;
|
|
3654
|
+
}
|
|
3655
|
+
};
|
|
3656
|
+
function _getDefaultBindGroupFactory(device) {
|
|
3657
|
+
device._factories.bindGroupFactory ||= new BindGroupFactory(device);
|
|
3658
|
+
return device._factories.bindGroupFactory;
|
|
3659
|
+
}
|
|
3660
|
+
function getBindGroupIndicesUpToMax(bindings) {
|
|
3661
|
+
const maxGroup = bindings.reduce((highestGroup, binding) => Math.max(highestGroup, binding.group), -1);
|
|
3662
|
+
return Array.from({ length: maxGroup + 1 }, (_, group) => group);
|
|
3663
|
+
}
|
|
3664
|
+
function hasBindingsInGroup(bindings, group) {
|
|
3665
|
+
return bindings.some((binding) => binding.group === group);
|
|
3666
|
+
}
|
|
3667
|
+
|
|
2494
3668
|
// dist/adapter/resources/render-pass.js
|
|
2495
3669
|
var _RenderPass = class extends Resource {
|
|
2496
3670
|
get [Symbol.toStringTag]() {
|
|
@@ -2529,28 +3703,6 @@ __publicField(RenderPass, "defaultProps", {
|
|
|
2529
3703
|
endTimestampIndex: void 0
|
|
2530
3704
|
});
|
|
2531
3705
|
|
|
2532
|
-
// dist/adapter/resources/compute-pipeline.js
|
|
2533
|
-
var _ComputePipeline = class extends Resource {
|
|
2534
|
-
get [Symbol.toStringTag]() {
|
|
2535
|
-
return "ComputePipeline";
|
|
2536
|
-
}
|
|
2537
|
-
hash = "";
|
|
2538
|
-
/** The merged shader layout */
|
|
2539
|
-
shaderLayout;
|
|
2540
|
-
constructor(device, props) {
|
|
2541
|
-
super(device, props, _ComputePipeline.defaultProps);
|
|
2542
|
-
this.shaderLayout = props.shaderLayout;
|
|
2543
|
-
}
|
|
2544
|
-
};
|
|
2545
|
-
var ComputePipeline = _ComputePipeline;
|
|
2546
|
-
__publicField(ComputePipeline, "defaultProps", {
|
|
2547
|
-
...Resource.defaultProps,
|
|
2548
|
-
shader: void 0,
|
|
2549
|
-
entryPoint: void 0,
|
|
2550
|
-
constants: {},
|
|
2551
|
-
shaderLayout: void 0
|
|
2552
|
-
});
|
|
2553
|
-
|
|
2554
3706
|
// dist/adapter/resources/compute-pass.js
|
|
2555
3707
|
var _ComputePass = class extends Resource {
|
|
2556
3708
|
constructor(device, props) {
|
|
@@ -2573,8 +3725,69 @@ var _CommandEncoder = class extends Resource {
|
|
|
2573
3725
|
get [Symbol.toStringTag]() {
|
|
2574
3726
|
return "CommandEncoder";
|
|
2575
3727
|
}
|
|
3728
|
+
_timeProfilingQuerySet = null;
|
|
3729
|
+
_timeProfilingSlotCount = 0;
|
|
3730
|
+
_gpuTimeMs;
|
|
2576
3731
|
constructor(device, props) {
|
|
2577
3732
|
super(device, props, _CommandEncoder.defaultProps);
|
|
3733
|
+
this._timeProfilingQuerySet = props.timeProfilingQuerySet ?? null;
|
|
3734
|
+
this._timeProfilingSlotCount = 0;
|
|
3735
|
+
this._gpuTimeMs = void 0;
|
|
3736
|
+
}
|
|
3737
|
+
/**
|
|
3738
|
+
* Reads all resolved timestamp pairs on the current profiler query set and caches the sum
|
|
3739
|
+
* as milliseconds on this encoder.
|
|
3740
|
+
*/
|
|
3741
|
+
async resolveTimeProfilingQuerySet() {
|
|
3742
|
+
this._gpuTimeMs = void 0;
|
|
3743
|
+
if (!this._timeProfilingQuerySet) {
|
|
3744
|
+
return;
|
|
3745
|
+
}
|
|
3746
|
+
const pairCount = Math.floor(this._timeProfilingSlotCount / 2);
|
|
3747
|
+
if (pairCount <= 0) {
|
|
3748
|
+
return;
|
|
3749
|
+
}
|
|
3750
|
+
const queryCount = pairCount * 2;
|
|
3751
|
+
const results = await this._timeProfilingQuerySet.readResults({
|
|
3752
|
+
firstQuery: 0,
|
|
3753
|
+
queryCount
|
|
3754
|
+
});
|
|
3755
|
+
let totalDurationNanoseconds = 0n;
|
|
3756
|
+
for (let queryIndex = 0; queryIndex < queryCount; queryIndex += 2) {
|
|
3757
|
+
totalDurationNanoseconds += results[queryIndex + 1] - results[queryIndex];
|
|
3758
|
+
}
|
|
3759
|
+
this._gpuTimeMs = Number(totalDurationNanoseconds) / 1e6;
|
|
3760
|
+
}
|
|
3761
|
+
/** Returns the number of query slots consumed by automatic pass profiling on this encoder. */
|
|
3762
|
+
getTimeProfilingSlotCount() {
|
|
3763
|
+
return this._timeProfilingSlotCount;
|
|
3764
|
+
}
|
|
3765
|
+
getTimeProfilingQuerySet() {
|
|
3766
|
+
return this._timeProfilingQuerySet;
|
|
3767
|
+
}
|
|
3768
|
+
/** Internal helper for auto-assigning timestamp slots to render/compute passes on this encoder. */
|
|
3769
|
+
_applyTimeProfilingToPassProps(props) {
|
|
3770
|
+
const passProps = props || {};
|
|
3771
|
+
if (!this._supportsTimestampQueries() || !this._timeProfilingQuerySet) {
|
|
3772
|
+
return passProps;
|
|
3773
|
+
}
|
|
3774
|
+
if (passProps.timestampQuerySet !== void 0 || passProps.beginTimestampIndex !== void 0 || passProps.endTimestampIndex !== void 0) {
|
|
3775
|
+
return passProps;
|
|
3776
|
+
}
|
|
3777
|
+
const beginTimestampIndex = this._timeProfilingSlotCount;
|
|
3778
|
+
if (beginTimestampIndex + 1 >= this._timeProfilingQuerySet.props.count) {
|
|
3779
|
+
return passProps;
|
|
3780
|
+
}
|
|
3781
|
+
this._timeProfilingSlotCount += 2;
|
|
3782
|
+
return {
|
|
3783
|
+
...passProps,
|
|
3784
|
+
timestampQuerySet: this._timeProfilingQuerySet,
|
|
3785
|
+
beginTimestampIndex,
|
|
3786
|
+
endTimestampIndex: beginTimestampIndex + 1
|
|
3787
|
+
};
|
|
3788
|
+
}
|
|
3789
|
+
_supportsTimestampQueries() {
|
|
3790
|
+
return this.device.features.has("timestamp-query");
|
|
2578
3791
|
}
|
|
2579
3792
|
};
|
|
2580
3793
|
var CommandEncoder = _CommandEncoder;
|
|
@@ -2583,7 +3796,8 @@ var CommandEncoder = _CommandEncoder;
|
|
|
2583
3796
|
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
2584
3797
|
__publicField(CommandEncoder, "defaultProps", {
|
|
2585
3798
|
...Resource.defaultProps,
|
|
2586
|
-
measureExecutionTime: void 0
|
|
3799
|
+
measureExecutionTime: void 0,
|
|
3800
|
+
timeProfilingQuerySet: void 0
|
|
2587
3801
|
});
|
|
2588
3802
|
|
|
2589
3803
|
// dist/adapter/resources/command-buffer.js
|
|
@@ -2600,13 +3814,22 @@ __publicField(CommandBuffer, "defaultProps", {
|
|
|
2600
3814
|
...Resource.defaultProps
|
|
2601
3815
|
});
|
|
2602
3816
|
|
|
2603
|
-
// dist/shadertypes/
|
|
3817
|
+
// dist/shadertypes/shader-types/shader-type-decoder.js
|
|
2604
3818
|
function getVariableShaderTypeInfo(format) {
|
|
2605
|
-
const
|
|
3819
|
+
const resolvedFormat = resolveVariableShaderTypeAlias(format);
|
|
3820
|
+
const decoded = UNIFORM_FORMATS[resolvedFormat];
|
|
3821
|
+
if (!decoded) {
|
|
3822
|
+
throw new Error(`Unsupported variable shader type: ${format}`);
|
|
3823
|
+
}
|
|
2606
3824
|
return decoded;
|
|
2607
3825
|
}
|
|
2608
3826
|
function getAttributeShaderTypeInfo(attributeType) {
|
|
2609
|
-
const
|
|
3827
|
+
const resolvedAttributeType = resolveAttributeShaderTypeAlias(attributeType);
|
|
3828
|
+
const decoded = TYPE_INFO[resolvedAttributeType];
|
|
3829
|
+
if (!decoded) {
|
|
3830
|
+
throw new Error(`Unsupported attribute shader type: ${attributeType}`);
|
|
3831
|
+
}
|
|
3832
|
+
const [primitiveType, components] = decoded;
|
|
2610
3833
|
const integer = primitiveType === "i32" || primitiveType === "u32";
|
|
2611
3834
|
const signed = primitiveType !== "u32";
|
|
2612
3835
|
const byteLength = PRIMITIVE_TYPE_SIZES[primitiveType] * components;
|
|
@@ -2618,6 +3841,33 @@ function getAttributeShaderTypeInfo(attributeType) {
|
|
|
2618
3841
|
signed
|
|
2619
3842
|
};
|
|
2620
3843
|
}
|
|
3844
|
+
var ShaderTypeDecoder = class {
|
|
3845
|
+
getVariableShaderTypeInfo(format) {
|
|
3846
|
+
return getVariableShaderTypeInfo(format);
|
|
3847
|
+
}
|
|
3848
|
+
getAttributeShaderTypeInfo(attributeType) {
|
|
3849
|
+
return getAttributeShaderTypeInfo(attributeType);
|
|
3850
|
+
}
|
|
3851
|
+
makeShaderAttributeType(primitiveType, components) {
|
|
3852
|
+
return makeShaderAttributeType(primitiveType, components);
|
|
3853
|
+
}
|
|
3854
|
+
resolveAttributeShaderTypeAlias(alias) {
|
|
3855
|
+
return resolveAttributeShaderTypeAlias(alias);
|
|
3856
|
+
}
|
|
3857
|
+
resolveVariableShaderTypeAlias(alias) {
|
|
3858
|
+
return resolveVariableShaderTypeAlias(alias);
|
|
3859
|
+
}
|
|
3860
|
+
};
|
|
3861
|
+
function makeShaderAttributeType(primitiveType, components) {
|
|
3862
|
+
return components === 1 ? primitiveType : `vec${components}<${primitiveType}>`;
|
|
3863
|
+
}
|
|
3864
|
+
function resolveAttributeShaderTypeAlias(alias) {
|
|
3865
|
+
return WGSL_ATTRIBUTE_TYPE_ALIAS_MAP[alias] || alias;
|
|
3866
|
+
}
|
|
3867
|
+
function resolveVariableShaderTypeAlias(alias) {
|
|
3868
|
+
return WGSL_VARIABLE_TYPE_ALIAS_MAP[alias] || alias;
|
|
3869
|
+
}
|
|
3870
|
+
var shaderTypeDecoder = new ShaderTypeDecoder();
|
|
2621
3871
|
var PRIMITIVE_TYPE_SIZES = {
|
|
2622
3872
|
f32: 4,
|
|
2623
3873
|
f16: 2,
|
|
@@ -2714,7 +3964,18 @@ var WGSL_ATTRIBUTE_TYPE_ALIAS_MAP = {
|
|
|
2714
3964
|
vec4h: "vec4<f16>"
|
|
2715
3965
|
};
|
|
2716
3966
|
var WGSL_VARIABLE_TYPE_ALIAS_MAP = {
|
|
2717
|
-
|
|
3967
|
+
vec2i: "vec2<i32>",
|
|
3968
|
+
vec3i: "vec3<i32>",
|
|
3969
|
+
vec4i: "vec4<i32>",
|
|
3970
|
+
vec2u: "vec2<u32>",
|
|
3971
|
+
vec3u: "vec3<u32>",
|
|
3972
|
+
vec4u: "vec4<u32>",
|
|
3973
|
+
vec2f: "vec2<f32>",
|
|
3974
|
+
vec3f: "vec3<f32>",
|
|
3975
|
+
vec4f: "vec4<f32>",
|
|
3976
|
+
vec2h: "vec2<f16>",
|
|
3977
|
+
vec3h: "vec3<f16>",
|
|
3978
|
+
vec4h: "vec4<f16>",
|
|
2718
3979
|
mat2x2f: "mat2x2<f32>",
|
|
2719
3980
|
mat2x3f: "mat2x3<f32>",
|
|
2720
3981
|
mat2x4f: "mat2x4<f32>",
|
|
@@ -2778,10 +4039,10 @@ function getAttributeInfoFromLayouts(shaderLayout, bufferLayout, name2) {
|
|
|
2778
4039
|
if (!shaderDeclaration) {
|
|
2779
4040
|
return null;
|
|
2780
4041
|
}
|
|
2781
|
-
const attributeTypeInfo = getAttributeShaderTypeInfo(shaderDeclaration.type);
|
|
2782
|
-
const defaultVertexFormat = getCompatibleVertexFormat(attributeTypeInfo);
|
|
4042
|
+
const attributeTypeInfo = shaderTypeDecoder.getAttributeShaderTypeInfo(shaderDeclaration.type);
|
|
4043
|
+
const defaultVertexFormat = vertexFormatDecoder.getCompatibleVertexFormat(attributeTypeInfo);
|
|
2783
4044
|
const vertexFormat = (bufferMapping == null ? void 0 : bufferMapping.vertexFormat) || defaultVertexFormat;
|
|
2784
|
-
const vertexFormatInfo = getVertexFormatInfo(vertexFormat);
|
|
4045
|
+
const vertexFormatInfo = vertexFormatDecoder.getVertexFormatInfo(vertexFormat);
|
|
2785
4046
|
return {
|
|
2786
4047
|
attributeName: (bufferMapping == null ? void 0 : bufferMapping.attributeName) || shaderDeclaration.name,
|
|
2787
4048
|
bufferName: (bufferMapping == null ? void 0 : bufferMapping.bufferName) || shaderDeclaration.name,
|
|
@@ -2850,7 +4111,7 @@ function getAttributeFromAttributesList(bufferLayouts, name2) {
|
|
|
2850
4111
|
let byteStride = bufferLayout.byteStride;
|
|
2851
4112
|
if (typeof bufferLayout.byteStride !== "number") {
|
|
2852
4113
|
for (const attributeMapping2 of bufferLayout.attributes || []) {
|
|
2853
|
-
const info = getVertexFormatInfo(attributeMapping2.format);
|
|
4114
|
+
const info = vertexFormatDecoder.getVertexFormatInfo(attributeMapping2.format);
|
|
2854
4115
|
byteStride += info.byteLength;
|
|
2855
4116
|
}
|
|
2856
4117
|
}
|
|
@@ -2936,7 +4197,9 @@ __publicField(QuerySet, "defaultProps", {
|
|
|
2936
4197
|
|
|
2937
4198
|
// dist/adapter/resources/fence.js
|
|
2938
4199
|
var _Fence = class extends Resource {
|
|
2939
|
-
[Symbol.toStringTag]
|
|
4200
|
+
get [Symbol.toStringTag]() {
|
|
4201
|
+
return "Fence";
|
|
4202
|
+
}
|
|
2940
4203
|
constructor(device, props = {}) {
|
|
2941
4204
|
super(device, props, _Fence.defaultProps);
|
|
2942
4205
|
}
|
|
@@ -2964,6 +4227,36 @@ __publicField(PipelineLayout, "defaultProps", {
|
|
|
2964
4227
|
}
|
|
2965
4228
|
});
|
|
2966
4229
|
|
|
4230
|
+
// dist/shadertypes/data-types/decode-data-types.js
|
|
4231
|
+
function alignTo(size, count) {
|
|
4232
|
+
switch (count) {
|
|
4233
|
+
case 1:
|
|
4234
|
+
return size;
|
|
4235
|
+
case 2:
|
|
4236
|
+
return size + size % 2;
|
|
4237
|
+
default:
|
|
4238
|
+
return size + (4 - size % 4) % 4;
|
|
4239
|
+
}
|
|
4240
|
+
}
|
|
4241
|
+
function getTypedArrayConstructor(type) {
|
|
4242
|
+
const [, , , , Constructor] = NORMALIZED_TYPE_MAP2[type];
|
|
4243
|
+
return Constructor;
|
|
4244
|
+
}
|
|
4245
|
+
var NORMALIZED_TYPE_MAP2 = {
|
|
4246
|
+
uint8: ["uint8", "u32", 1, false, Uint8Array],
|
|
4247
|
+
sint8: ["sint8", "i32", 1, false, Int8Array],
|
|
4248
|
+
unorm8: ["uint8", "f32", 1, true, Uint8Array],
|
|
4249
|
+
snorm8: ["sint8", "f32", 1, true, Int8Array],
|
|
4250
|
+
uint16: ["uint16", "u32", 2, false, Uint16Array],
|
|
4251
|
+
sint16: ["sint16", "i32", 2, false, Int16Array],
|
|
4252
|
+
unorm16: ["uint16", "u32", 2, true, Uint16Array],
|
|
4253
|
+
snorm16: ["sint16", "i32", 2, true, Int16Array],
|
|
4254
|
+
float16: ["float16", "f16", 2, false, Uint16Array],
|
|
4255
|
+
float32: ["float32", "f32", 4, false, Float32Array],
|
|
4256
|
+
uint32: ["uint32", "u32", 4, false, Uint32Array],
|
|
4257
|
+
sint32: ["sint32", "i32", 4, false, Int32Array]
|
|
4258
|
+
};
|
|
4259
|
+
|
|
2967
4260
|
// dist/utils/array-utils-flat.js
|
|
2968
4261
|
var arrayBuffer;
|
|
2969
4262
|
function getScratchArrayBuffer(byteLength) {
|
|
@@ -2977,19 +4270,32 @@ function getScratchArray(Type, length) {
|
|
|
2977
4270
|
return new Type(scratchArrayBuffer, 0, length);
|
|
2978
4271
|
}
|
|
2979
4272
|
|
|
4273
|
+
// dist/utils/is-array.js
|
|
4274
|
+
function isTypedArray(value) {
|
|
4275
|
+
return ArrayBuffer.isView(value) && !(value instanceof DataView);
|
|
4276
|
+
}
|
|
4277
|
+
function isNumberArray(value) {
|
|
4278
|
+
if (Array.isArray(value)) {
|
|
4279
|
+
return value.length === 0 || typeof value[0] === "number";
|
|
4280
|
+
}
|
|
4281
|
+
return isTypedArray(value);
|
|
4282
|
+
}
|
|
4283
|
+
|
|
2980
4284
|
// dist/portable/uniform-buffer-layout.js
|
|
2981
4285
|
var minBufferSize = 1024;
|
|
2982
4286
|
var UniformBufferLayout = class {
|
|
2983
4287
|
layout = {};
|
|
4288
|
+
uniformTypes;
|
|
2984
4289
|
/** number of bytes needed for buffer allocation */
|
|
2985
4290
|
byteLength;
|
|
2986
4291
|
/** Create a new UniformBufferLayout given a map of attributes. */
|
|
2987
|
-
constructor(uniformTypes
|
|
4292
|
+
constructor(uniformTypes) {
|
|
4293
|
+
this.uniformTypes = { ...uniformTypes };
|
|
2988
4294
|
let size = 0;
|
|
2989
|
-
for (const [key, uniformType] of Object.entries(uniformTypes)) {
|
|
2990
|
-
size = this._addToLayout(key, uniformType, size
|
|
4295
|
+
for (const [key, uniformType] of Object.entries(this.uniformTypes)) {
|
|
4296
|
+
size = this._addToLayout(key, uniformType, size);
|
|
2991
4297
|
}
|
|
2992
|
-
size
|
|
4298
|
+
size = alignTo(size, 4);
|
|
2993
4299
|
this.byteLength = Math.max(size * 4, minBufferSize);
|
|
2994
4300
|
}
|
|
2995
4301
|
/** Does this layout have a field with specified name */
|
|
@@ -3001,115 +4307,255 @@ var UniformBufferLayout = class {
|
|
|
3001
4307
|
const layout = this.layout[name2];
|
|
3002
4308
|
return layout;
|
|
3003
4309
|
}
|
|
4310
|
+
/** Flatten nested uniform values into leaf-path values understood by UniformBlock. */
|
|
4311
|
+
getFlatUniformValues(uniformValues) {
|
|
4312
|
+
const flattenedUniformValues = {};
|
|
4313
|
+
for (const [name2, value] of Object.entries(uniformValues)) {
|
|
4314
|
+
const uniformType = this.uniformTypes[name2];
|
|
4315
|
+
if (uniformType) {
|
|
4316
|
+
this._flattenCompositeValue(flattenedUniformValues, name2, uniformType, value);
|
|
4317
|
+
} else if (this.layout[name2]) {
|
|
4318
|
+
flattenedUniformValues[name2] = value;
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
return flattenedUniformValues;
|
|
4322
|
+
}
|
|
3004
4323
|
/** Get the data for the complete buffer */
|
|
3005
4324
|
getData(uniformValues) {
|
|
3006
4325
|
const buffer = getScratchArrayBuffer(this.byteLength);
|
|
4326
|
+
new Uint8Array(buffer, 0, this.byteLength).fill(0);
|
|
3007
4327
|
const typedArrays = {
|
|
3008
4328
|
i32: new Int32Array(buffer),
|
|
3009
4329
|
u32: new Uint32Array(buffer),
|
|
3010
4330
|
f32: new Float32Array(buffer),
|
|
3011
4331
|
f16: new Uint16Array(buffer)
|
|
3012
4332
|
};
|
|
3013
|
-
|
|
3014
|
-
|
|
4333
|
+
const flattenedUniformValues = this.getFlatUniformValues(uniformValues);
|
|
4334
|
+
for (const [name2, value] of Object.entries(flattenedUniformValues)) {
|
|
4335
|
+
this._writeLeafValue(typedArrays, name2, value);
|
|
3015
4336
|
}
|
|
3016
4337
|
return new Uint8Array(buffer, 0, this.byteLength);
|
|
3017
4338
|
}
|
|
3018
4339
|
// Recursively add a uniform to the layout
|
|
3019
|
-
_addToLayout(name2, type, offset
|
|
4340
|
+
_addToLayout(name2, type, offset) {
|
|
3020
4341
|
if (typeof type === "string") {
|
|
3021
|
-
const info =
|
|
3022
|
-
const
|
|
3023
|
-
const alignedOffset = alignTo(offset, info.components);
|
|
4342
|
+
const info = getLeafLayoutInfo(type);
|
|
4343
|
+
const alignedOffset = alignTo(offset, info.alignment);
|
|
3024
4344
|
this.layout[name2] = {
|
|
3025
4345
|
offset: alignedOffset,
|
|
3026
|
-
|
|
3027
|
-
type: info.type
|
|
4346
|
+
...info
|
|
3028
4347
|
};
|
|
3029
|
-
return alignedOffset +
|
|
4348
|
+
return alignedOffset + info.size;
|
|
3030
4349
|
}
|
|
3031
4350
|
if (Array.isArray(type)) {
|
|
4351
|
+
if (Array.isArray(type[0])) {
|
|
4352
|
+
throw new Error(`Nested arrays are not supported for ${name2}`);
|
|
4353
|
+
}
|
|
3032
4354
|
const elementType = type[0];
|
|
3033
|
-
const length =
|
|
3034
|
-
|
|
4355
|
+
const length = type[1];
|
|
4356
|
+
const stride = alignTo(getTypeSize(elementType), 4);
|
|
4357
|
+
const arrayOffset = alignTo(offset, 4);
|
|
3035
4358
|
for (let i = 0; i < length; i++) {
|
|
3036
|
-
|
|
4359
|
+
this._addToLayout(`${name2}[${i}]`, elementType, arrayOffset + i * stride);
|
|
3037
4360
|
}
|
|
3038
|
-
return arrayOffset;
|
|
4361
|
+
return arrayOffset + stride * length;
|
|
3039
4362
|
}
|
|
3040
|
-
if (
|
|
4363
|
+
if (isCompositeShaderTypeStruct(type)) {
|
|
3041
4364
|
let structOffset = alignTo(offset, 4);
|
|
3042
4365
|
for (const [memberName, memberType] of Object.entries(type)) {
|
|
3043
4366
|
structOffset = this._addToLayout(`${name2}.${memberName}`, memberType, structOffset);
|
|
3044
4367
|
}
|
|
3045
|
-
return structOffset;
|
|
4368
|
+
return alignTo(structOffset, 4);
|
|
3046
4369
|
}
|
|
3047
4370
|
throw new Error(`Unsupported CompositeShaderType for ${name2}`);
|
|
3048
4371
|
}
|
|
3049
|
-
|
|
3050
|
-
if (
|
|
3051
|
-
|
|
4372
|
+
_flattenCompositeValue(flattenedUniformValues, baseName, uniformType, value) {
|
|
4373
|
+
if (value === void 0) {
|
|
4374
|
+
return;
|
|
4375
|
+
}
|
|
4376
|
+
if (typeof uniformType === "string" || this.layout[baseName]) {
|
|
4377
|
+
flattenedUniformValues[baseName] = value;
|
|
3052
4378
|
return;
|
|
3053
4379
|
}
|
|
3054
|
-
if (Array.isArray(
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
4380
|
+
if (Array.isArray(uniformType)) {
|
|
4381
|
+
const elementType = uniformType[0];
|
|
4382
|
+
const length = uniformType[1];
|
|
4383
|
+
if (Array.isArray(elementType)) {
|
|
4384
|
+
throw new Error(`Nested arrays are not supported for ${baseName}`);
|
|
4385
|
+
}
|
|
4386
|
+
if (typeof elementType === "string" && isNumberArray(value)) {
|
|
4387
|
+
this._flattenPackedArray(flattenedUniformValues, baseName, elementType, length, value);
|
|
4388
|
+
return;
|
|
4389
|
+
}
|
|
4390
|
+
if (!Array.isArray(value)) {
|
|
4391
|
+
log.warn(`Unsupported uniform array value for ${baseName}:`, value)();
|
|
4392
|
+
return;
|
|
4393
|
+
}
|
|
4394
|
+
for (let index = 0; index < Math.min(value.length, length); index++) {
|
|
4395
|
+
const elementValue = value[index];
|
|
4396
|
+
if (elementValue === void 0) {
|
|
4397
|
+
continue;
|
|
4398
|
+
}
|
|
4399
|
+
this._flattenCompositeValue(flattenedUniformValues, `${baseName}[${index}]`, elementType, elementValue);
|
|
3059
4400
|
}
|
|
3060
4401
|
return;
|
|
3061
4402
|
}
|
|
3062
|
-
if (
|
|
4403
|
+
if (isCompositeShaderTypeStruct(uniformType) && isCompositeUniformObject(value)) {
|
|
3063
4404
|
for (const [key, subValue] of Object.entries(value)) {
|
|
4405
|
+
if (subValue === void 0) {
|
|
4406
|
+
continue;
|
|
4407
|
+
}
|
|
3064
4408
|
const nestedName = `${baseName}.${key}`;
|
|
3065
|
-
this.
|
|
4409
|
+
this._flattenCompositeValue(flattenedUniformValues, nestedName, uniformType[key], subValue);
|
|
3066
4410
|
}
|
|
3067
4411
|
return;
|
|
3068
4412
|
}
|
|
3069
4413
|
log.warn(`Unsupported uniform value for ${baseName}:`, value)();
|
|
3070
4414
|
}
|
|
3071
|
-
|
|
4415
|
+
_flattenPackedArray(flattenedUniformValues, baseName, elementType, length, value) {
|
|
4416
|
+
const numericValue = value;
|
|
4417
|
+
const elementLayout = getLeafLayoutInfo(elementType);
|
|
4418
|
+
const packedElementLength = elementLayout.components;
|
|
4419
|
+
for (let index = 0; index < length; index++) {
|
|
4420
|
+
const start = index * packedElementLength;
|
|
4421
|
+
if (start >= numericValue.length) {
|
|
4422
|
+
break;
|
|
4423
|
+
}
|
|
4424
|
+
if (packedElementLength === 1) {
|
|
4425
|
+
flattenedUniformValues[`${baseName}[${index}]`] = Number(numericValue[start]);
|
|
4426
|
+
} else {
|
|
4427
|
+
flattenedUniformValues[`${baseName}[${index}]`] = sliceNumericArray(value, start, start + packedElementLength);
|
|
4428
|
+
}
|
|
4429
|
+
}
|
|
4430
|
+
}
|
|
4431
|
+
_writeLeafValue(typedArrays, name2, value) {
|
|
3072
4432
|
const layout = this.layout[name2];
|
|
3073
4433
|
if (!layout) {
|
|
3074
4434
|
log.warn(`Uniform ${name2} not found in layout`)();
|
|
3075
4435
|
return;
|
|
3076
4436
|
}
|
|
3077
|
-
const { type,
|
|
4437
|
+
const { type, components, columns, rows, offset } = layout;
|
|
3078
4438
|
const array = typedArrays[type];
|
|
3079
|
-
if (
|
|
4439
|
+
if (components === 1) {
|
|
3080
4440
|
array[offset] = Number(value);
|
|
3081
|
-
|
|
3082
|
-
|
|
4441
|
+
return;
|
|
4442
|
+
}
|
|
4443
|
+
const sourceValue = value;
|
|
4444
|
+
if (columns === 1) {
|
|
4445
|
+
for (let componentIndex = 0; componentIndex < components; componentIndex++) {
|
|
4446
|
+
array[offset + componentIndex] = Number(sourceValue[componentIndex] ?? 0);
|
|
4447
|
+
}
|
|
4448
|
+
return;
|
|
4449
|
+
}
|
|
4450
|
+
let sourceIndex = 0;
|
|
4451
|
+
for (let columnIndex = 0; columnIndex < columns; columnIndex++) {
|
|
4452
|
+
const columnOffset = offset + columnIndex * 4;
|
|
4453
|
+
for (let rowIndex = 0; rowIndex < rows; rowIndex++) {
|
|
4454
|
+
array[columnOffset + rowIndex] = Number(sourceValue[sourceIndex++] ?? 0);
|
|
4455
|
+
}
|
|
3083
4456
|
}
|
|
3084
4457
|
}
|
|
3085
4458
|
};
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
4459
|
+
function getTypeSize(type) {
|
|
4460
|
+
if (typeof type === "string") {
|
|
4461
|
+
return getLeafLayoutInfo(type).size;
|
|
4462
|
+
}
|
|
4463
|
+
if (Array.isArray(type)) {
|
|
4464
|
+
const elementType = type[0];
|
|
4465
|
+
const length = type[1];
|
|
4466
|
+
if (Array.isArray(elementType)) {
|
|
4467
|
+
throw new Error("Nested arrays are not supported");
|
|
4468
|
+
}
|
|
4469
|
+
return alignTo(getTypeSize(elementType), 4) * length;
|
|
4470
|
+
}
|
|
4471
|
+
let size = 0;
|
|
4472
|
+
for (const memberType of Object.values(type)) {
|
|
4473
|
+
const compositeMemberType = memberType;
|
|
4474
|
+
size = alignTo(size, getTypeAlignment(compositeMemberType));
|
|
4475
|
+
size += getTypeSize(compositeMemberType);
|
|
4476
|
+
}
|
|
4477
|
+
return alignTo(size, 4);
|
|
3090
4478
|
}
|
|
3091
|
-
function
|
|
3092
|
-
if (
|
|
3093
|
-
return
|
|
4479
|
+
function getTypeAlignment(type) {
|
|
4480
|
+
if (typeof type === "string") {
|
|
4481
|
+
return getLeafLayoutInfo(type).alignment;
|
|
3094
4482
|
}
|
|
3095
|
-
|
|
4483
|
+
if (Array.isArray(type)) {
|
|
4484
|
+
return 4;
|
|
4485
|
+
}
|
|
4486
|
+
return 4;
|
|
4487
|
+
}
|
|
4488
|
+
function getLeafLayoutInfo(type) {
|
|
4489
|
+
const resolvedType = resolveVariableShaderTypeAlias(type);
|
|
4490
|
+
const decodedType = getVariableShaderTypeInfo(resolvedType);
|
|
4491
|
+
const matrixMatch = /^mat(\d)x(\d)<.+>$/.exec(resolvedType);
|
|
4492
|
+
if (matrixMatch) {
|
|
4493
|
+
const columns = Number(matrixMatch[1]);
|
|
4494
|
+
const rows = Number(matrixMatch[2]);
|
|
4495
|
+
return {
|
|
4496
|
+
alignment: 4,
|
|
4497
|
+
size: columns * 4,
|
|
4498
|
+
components: columns * rows,
|
|
4499
|
+
columns,
|
|
4500
|
+
rows,
|
|
4501
|
+
shaderType: resolvedType,
|
|
4502
|
+
type: decodedType.type
|
|
4503
|
+
};
|
|
4504
|
+
}
|
|
4505
|
+
const vectorMatch = /^vec(\d)<.+>$/.exec(resolvedType);
|
|
4506
|
+
if (vectorMatch) {
|
|
4507
|
+
const components = Number(vectorMatch[1]);
|
|
4508
|
+
return {
|
|
4509
|
+
alignment: components === 2 ? 2 : 4,
|
|
4510
|
+
size: components === 3 ? 4 : components,
|
|
4511
|
+
components,
|
|
4512
|
+
columns: 1,
|
|
4513
|
+
rows: components,
|
|
4514
|
+
shaderType: resolvedType,
|
|
4515
|
+
type: decodedType.type
|
|
4516
|
+
};
|
|
4517
|
+
}
|
|
4518
|
+
return {
|
|
4519
|
+
alignment: 1,
|
|
4520
|
+
size: 1,
|
|
4521
|
+
components: 1,
|
|
4522
|
+
columns: 1,
|
|
4523
|
+
rows: 1,
|
|
4524
|
+
shaderType: resolvedType,
|
|
4525
|
+
type: decodedType.type
|
|
4526
|
+
};
|
|
4527
|
+
}
|
|
4528
|
+
function isCompositeShaderTypeStruct(value) {
|
|
4529
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4530
|
+
}
|
|
4531
|
+
function isCompositeUniformObject(value) {
|
|
4532
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value) && !ArrayBuffer.isView(value);
|
|
4533
|
+
}
|
|
4534
|
+
function sliceNumericArray(value, start, end) {
|
|
4535
|
+
return Array.prototype.slice.call(value, start, end);
|
|
3096
4536
|
}
|
|
3097
4537
|
|
|
3098
4538
|
// dist/utils/array-equal.js
|
|
4539
|
+
var MAX_ELEMENTWISE_ARRAY_COMPARE_LENGTH = 128;
|
|
3099
4540
|
function arrayEqual(a, b, limit = 16) {
|
|
3100
|
-
if (a
|
|
3101
|
-
return
|
|
4541
|
+
if (a === b) {
|
|
4542
|
+
return true;
|
|
3102
4543
|
}
|
|
3103
4544
|
const arrayA = a;
|
|
3104
4545
|
const arrayB = b;
|
|
3105
|
-
if (!isNumberArray(arrayA)) {
|
|
4546
|
+
if (!isNumberArray(arrayA) || !isNumberArray(arrayB)) {
|
|
3106
4547
|
return false;
|
|
3107
4548
|
}
|
|
3108
|
-
if (
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
4549
|
+
if (arrayA.length !== arrayB.length) {
|
|
4550
|
+
return false;
|
|
4551
|
+
}
|
|
4552
|
+
const maxCompareLength = Math.min(limit, MAX_ELEMENTWISE_ARRAY_COMPARE_LENGTH);
|
|
4553
|
+
if (arrayA.length > maxCompareLength) {
|
|
4554
|
+
return false;
|
|
4555
|
+
}
|
|
4556
|
+
for (let i = 0; i < arrayA.length; ++i) {
|
|
4557
|
+
if (arrayB[i] !== arrayA[i]) {
|
|
4558
|
+
return false;
|
|
3113
4559
|
}
|
|
3114
4560
|
}
|
|
3115
4561
|
return true;
|
|
@@ -3187,10 +4633,10 @@ var UniformStore = class {
|
|
|
3187
4633
|
constructor(blocks) {
|
|
3188
4634
|
for (const [bufferName, block] of Object.entries(blocks)) {
|
|
3189
4635
|
const uniformBufferName = bufferName;
|
|
3190
|
-
const uniformBufferLayout = new UniformBufferLayout(block.uniformTypes ?? {}
|
|
4636
|
+
const uniformBufferLayout = new UniformBufferLayout(block.uniformTypes ?? {});
|
|
3191
4637
|
this.uniformBufferLayouts.set(uniformBufferName, uniformBufferLayout);
|
|
3192
4638
|
const uniformBlock = new UniformBlock({ name: bufferName });
|
|
3193
|
-
uniformBlock.setUniforms(block.defaultUniforms || {});
|
|
4639
|
+
uniformBlock.setUniforms(uniformBufferLayout.getFlatUniformValues(block.defaultUniforms || {}));
|
|
3194
4640
|
this.uniformBlocks.set(uniformBufferName, uniformBlock);
|
|
3195
4641
|
}
|
|
3196
4642
|
}
|
|
@@ -3207,7 +4653,10 @@ var UniformStore = class {
|
|
|
3207
4653
|
setUniforms(uniforms) {
|
|
3208
4654
|
var _a;
|
|
3209
4655
|
for (const [blockName, uniformValues] of Object.entries(uniforms)) {
|
|
3210
|
-
|
|
4656
|
+
const uniformBufferName = blockName;
|
|
4657
|
+
const uniformBufferLayout = this.uniformBufferLayouts.get(uniformBufferName);
|
|
4658
|
+
const flattenedUniforms = uniformBufferLayout == null ? void 0 : uniformBufferLayout.getFlatUniformValues(uniformValues || {});
|
|
4659
|
+
(_a = this.uniformBlocks.get(uniformBufferName)) == null ? void 0 : _a.setUniforms(flattenedUniforms || {});
|
|
3211
4660
|
}
|
|
3212
4661
|
this.updateUniformBuffers();
|
|
3213
4662
|
}
|
|
@@ -3281,7 +4730,7 @@ var UniformStore = class {
|
|
|
3281
4730
|
}
|
|
3282
4731
|
};
|
|
3283
4732
|
|
|
3284
|
-
// dist/shadertypes/
|
|
4733
|
+
// dist/shadertypes/texture-types/texture-layout.js
|
|
3285
4734
|
function getTextureImageView(arrayBuffer2, memoryLayout, format, image = 0) {
|
|
3286
4735
|
const formatInfo = textureFormatDecoder.getInfo(format);
|
|
3287
4736
|
const bytesPerComponent = formatInfo.bytesPerPixel / formatInfo.components;
|
|
@@ -3319,7 +4768,7 @@ function setTextureImageData(arrayBuffer2, memoryLayout, format, data, image = 0
|
|
|
3319
4768
|
typedArray.set(subArray, offset);
|
|
3320
4769
|
}
|
|
3321
4770
|
|
|
3322
|
-
// dist/shadertypes/
|
|
4771
|
+
// dist/shadertypes/texture-types/pixel-utils.js
|
|
3323
4772
|
function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
3324
4773
|
if (x < 0 || x >= pixelData.width || y < 0 || y >= pixelData.height) {
|
|
3325
4774
|
throw new Error("Coordinates out of bounds.");
|