@carbonenginejs/runtime-resource 0.10.0 → 0.11.0
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/format/effect/effectPermutationGraph.js +257 -0
- package/dist/format/effect/effectPermutationGraph.js.map +1 -0
- package/dist/format/effect/effectReflectionPackage.js +636 -0
- package/dist/format/effect/effectReflectionPackage.js.map +1 -0
- package/dist/format/effect/sha256.js +114 -0
- package/dist/format/effect/sha256.js.map +1 -0
- package/dist/formats/dxbc/CjsDxbcFormat.js +142 -0
- package/dist/formats/dxbc/CjsDxbcFormat.js.map +1 -0
- package/dist/formats/dxbc/core/DxbcReader.js +266 -0
- package/dist/formats/dxbc/core/DxbcReader.js.map +1 -0
- package/dist/formats/dxbc/core/container.js +169 -0
- package/dist/formats/dxbc/core/container.js.map +1 -0
- package/dist/formats/dxbc/core/decoder.js +789 -0
- package/dist/formats/dxbc/core/decoder.js.map +1 -0
- package/dist/formats/dxbc/core/errors.js +19 -0
- package/dist/formats/dxbc/core/errors.js.map +1 -0
- package/dist/formats/dxbc/core/helpers.js +220 -0
- package/dist/formats/dxbc/core/helpers.js.map +1 -0
- package/dist/formats/dxbc/core/opcodes.js +45 -0
- package/dist/formats/dxbc/core/opcodes.js.map +1 -0
- package/dist/formats/dxbc/core/program.js +91 -0
- package/dist/formats/dxbc/core/program.js.map +1 -0
- package/dist/formats/dxbc/core/signature.js +172 -0
- package/dist/formats/dxbc/core/signature.js.map +1 -0
- package/dist/formats/dxbc/index.js +2 -0
- package/dist/formats/dxbc/index.js.map +1 -0
- package/dist/formats/hlsl/CjsHlslFormat.js +254 -0
- package/dist/formats/hlsl/CjsHlslFormat.js.map +1 -0
- package/dist/formats/hlsl/core/HlslBinaryUtils.js +15 -0
- package/dist/formats/hlsl/core/HlslBinaryUtils.js.map +1 -0
- package/dist/formats/hlsl/core/HlslEffectReadError.js +19 -0
- package/dist/formats/hlsl/core/HlslEffectReadError.js.map +1 -0
- package/dist/formats/hlsl/core/HlslEffectStateManager.js +130 -0
- package/dist/formats/hlsl/core/HlslEffectStateManager.js.map +1 -0
- package/dist/formats/hlsl/core/HlslReader.js +266 -0
- package/dist/formats/hlsl/core/HlslReader.js.map +1 -0
- package/dist/formats/hlsl/core/HlslRenderStateSetup.js +37 -0
- package/dist/formats/hlsl/core/HlslRenderStateSetup.js.map +1 -0
- package/dist/formats/hlsl/core/HlslResourceSetDescription.js +94 -0
- package/dist/formats/hlsl/core/HlslResourceSetDescription.js.map +1 -0
- package/dist/formats/hlsl/core/HlslShaderBytecode.js +44 -0
- package/dist/formats/hlsl/core/HlslShaderBytecode.js.map +1 -0
- package/dist/formats/hlsl/core/analysis.js +51 -0
- package/dist/formats/hlsl/core/analysis.js.map +1 -0
- package/dist/formats/hlsl/core/helpers.js +270 -0
- package/dist/formats/hlsl/core/helpers.js.map +1 -0
- package/dist/formats/hlsl/core/json.js +284 -0
- package/dist/formats/hlsl/core/json.js.map +1 -0
- package/dist/formats/hlsl/core/metadata.js +327 -0
- package/dist/formats/hlsl/core/metadata.js.map +1 -0
- package/dist/formats/hlsl/core/portableReflection.js +848 -0
- package/dist/formats/hlsl/core/portableReflection.js.map +1 -0
- package/dist/formats/hlsl/core/render-states.js +280 -0
- package/dist/formats/hlsl/core/render-states.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/HlslRenderContextEnum.js +43 -0
- package/dist/formats/hlsl/core/tr2/HlslRenderContextEnum.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js +294 -0
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/resources/HlslShaderPermutation.js +33 -0
- package/dist/formats/hlsl/core/tr2/resources/HlslShaderPermutation.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +416 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectConstant.js +40 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectConstant.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js +742 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectLibrary.js +52 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectLibrary.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectParameterAnnotation.js +38 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectParameterAnnotation.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectResource.js +50 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectResource.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectStageInput.js +86 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectStageInput.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectTechnique.js +31 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectTechnique.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslPass.js +42 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslPass.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerDescription.js +55 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerDescription.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerSetup.js +29 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerSetup.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslShader.js +220 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslShader.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslShaderOption.js +30 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslShaderOption.js.map +1 -0
- package/dist/formats/hlsl/index.js +2 -0
- package/dist/formats/hlsl/index.js.map +1 -0
- package/dist/formats/hlsl/portable.js +2 -0
- package/dist/formats/hlsl/portable.js.map +1 -0
- package/dist/formats/index.js +4 -0
- package/dist/formats/index.js.map +1 -1
- package/dist/formats/webgl/CjsWebglFormat.js +221 -0
- package/dist/formats/webgl/CjsWebglFormat.js.map +1 -0
- package/dist/formats/webgl/core/cewg/CewgPackage.js +339 -0
- package/dist/formats/webgl/core/cewg/CewgPackage.js.map +1 -0
- package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js +104 -0
- package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js.map +1 -0
- package/dist/formats/webgl/core/cewg/binary.js +101 -0
- package/dist/formats/webgl/core/cewg/binary.js.map +1 -0
- package/dist/formats/webgl/core/cewgCompleteness.js +81 -0
- package/dist/formats/webgl/core/cewgCompleteness.js.map +1 -0
- package/dist/formats/webgl/core/effectPackage.js +789 -0
- package/dist/formats/webgl/core/effectPackage.js.map +1 -0
- package/dist/formats/webgl/core/effectPackageValidation.js +331 -0
- package/dist/formats/webgl/core/effectPackageValidation.js.map +1 -0
- package/dist/formats/webgl/core/errors.js +27 -0
- package/dist/formats/webgl/core/errors.js.map +1 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +2678 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslHelpers.js +89 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslHelpers.js.map +1 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js +428 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js.map +1 -0
- package/dist/formats/webgl/core/helpers.js +306 -0
- package/dist/formats/webgl/core/helpers.js.map +1 -0
- package/dist/formats/webgl/index.js +2 -0
- package/dist/formats/webgl/index.js.map +1 -0
- package/dist/formats/webgpu/CjsWebgpuFormat.js +376 -0
- package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackage.js +415 -0
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackage.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackageBuilder.js +100 -0
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackageBuilder.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/binary.js +93 -0
- package/dist/formats/webgpu/core/cewgpu/binary.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/tags.js +17 -0
- package/dist/formats/webgpu/core/cewgpu/tags.js.map +1 -0
- package/dist/formats/webgpu/core/effectAnalysis.js +82 -0
- package/dist/formats/webgpu/core/effectAnalysis.js.map +1 -0
- package/dist/formats/webgpu/core/effectBackendBodySet.js +305 -0
- package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -0
- package/dist/formats/webgpu/core/effectPackageValidation.js +1078 -0
- package/dist/formats/webgpu/core/effectPackageValidation.js.map +1 -0
- package/dist/formats/webgpu/core/errors.js +20 -0
- package/dist/formats/webgpu/core/errors.js.map +1 -0
- package/dist/formats/webgpu/core/helpers.js +448 -0
- package/dist/formats/webgpu/core/helpers.js.map +1 -0
- package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js +223 -0
- package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js.map +1 -0
- package/dist/formats/webgpu/core/ir/buildControlFlow.js +220 -0
- package/dist/formats/webgpu/core/ir/buildControlFlow.js.map +1 -0
- package/dist/formats/webgpu/core/ir/indexableTemps.js +137 -0
- package/dist/formats/webgpu/core/ir/indexableTemps.js.map +1 -0
- package/dist/formats/webgpu/core/ir/inferValueTypes.js +454 -0
- package/dist/formats/webgpu/core/ir/inferValueTypes.js.map +1 -0
- package/dist/formats/webgpu/core/ir/lowerDxbcToIr.js +494 -0
- package/dist/formats/webgpu/core/ir/lowerDxbcToIr.js.map +1 -0
- package/dist/formats/webgpu/core/ir/resolveRegisterFlow.js +177 -0
- package/dist/formats/webgpu/core/ir/resolveRegisterFlow.js.map +1 -0
- package/dist/formats/webgpu/core/ir/sourceLanes.js +61 -0
- package/dist/formats/webgpu/core/ir/sourceLanes.js.map +1 -0
- package/dist/formats/webgpu/core/packageEffect.js +300 -0
- package/dist/formats/webgpu/core/packageEffect.js.map +1 -0
- package/dist/formats/webgpu/core/packageEffectSelection.js +164 -0
- package/dist/formats/webgpu/core/packageEffectSelection.js.map +1 -0
- package/dist/formats/webgpu/core/packageMetadata.js +8 -0
- package/dist/formats/webgpu/core/packageMetadata.js.map +1 -0
- package/dist/formats/webgpu/core/schema.js +4 -0
- package/dist/formats/webgpu/core/schema.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +275 -0
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js +182 -0
- package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js +324 -0
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/emitWgsl.js +356 -0
- package/dist/formats/webgpu/core/wgsl/emitWgsl.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/hoistEscapingValues.js +77 -0
- package/dist/formats/webgpu/core/wgsl/hoistEscapingValues.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerBindingLayout.js +451 -0
- package/dist/formats/webgpu/core/wgsl/lowerBindingLayout.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js +754 -0
- package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerCreateHistogramsComputeProgram.js +457 -0
- package/dist/formats/webgpu/core/wgsl/lowerCreateHistogramsComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerFragmentProgram.js +1572 -0
- package/dist/formats/webgpu/core/wgsl/lowerFragmentProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerMergeHistogramsComputeProgram.js +659 -0
- package/dist/formats/webgpu/core/wgsl/lowerMergeHistogramsComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerParticleClearComputePrograms.js +734 -0
- package/dist/formats/webgpu/core/wgsl/lowerParticleClearComputePrograms.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerParticleEmitComputeProgram.js +583 -0
- package/dist/formats/webgpu/core/wgsl/lowerParticleEmitComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerSkinVerticesComputeProgram.js +621 -0
- package/dist/formats/webgpu/core/wgsl/lowerSkinVerticesComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortComputeProgram.js +824 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortInnerComputeProgram.js +697 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortInnerComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortStepComputeProgram.js +559 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortStepComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerVertexProgram.js +1328 -0
- package/dist/formats/webgpu/core/wgsl/lowerVertexProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/particleEmitSemanticDigest.js +110 -0
- package/dist/formats/webgpu/core/wgsl/particleEmitSemanticDigest.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/precisionControls.js +55 -0
- package/dist/formats/webgpu/core/wgsl/precisionControls.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/selectionPlans.js +758 -0
- package/dist/formats/webgpu/core/wgsl/selectionPlans.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/uniformity.js +78 -0
- package/dist/formats/webgpu/core/wgsl/uniformity.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/validateExactComputeIr.js +196 -0
- package/dist/formats/webgpu/core/wgsl/validateExactComputeIr.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/validateHandleOperand.js +37 -0
- package/dist/formats/webgpu/core/wgsl/validateHandleOperand.js.map +1 -0
- package/dist/formats/webgpu/index.js +2 -0
- package/dist/formats/webgpu/index.js.map +1 -0
- package/dist/resource/shader/Tr2EffectRes.js +159 -150
- package/dist/resource/shader/Tr2EffectRes.js.map +1 -1
- package/dist/resource/shader/Tr2MaterialArea.js +23 -28
- package/dist/resource/shader/Tr2MaterialArea.js.map +1 -1
- package/dist/resource/shader/Tr2MaterialMesh.js +21 -27
- package/dist/resource/shader/Tr2MaterialMesh.js.map +1 -1
- package/dist/resource/shader/Tr2MaterialRes.js +24 -29
- package/dist/resource/shader/Tr2MaterialRes.js.map +1 -1
- package/dist/resource/shader/Tr2Shader.js +45 -39
- package/dist/resource/shader/Tr2Shader.js.map +1 -1
- package/dist/resource/shader/Tr2ShaderPermutation.js +30 -32
- package/dist/resource/shader/Tr2ShaderPermutation.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectConstant.js +113 -78
- package/dist/resource/shader/reflection/Tr2EffectConstant.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectDefine.js +17 -23
- package/dist/resource/shader/reflection/Tr2EffectDefine.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectDescription.js +23 -29
- package/dist/resource/shader/reflection/Tr2EffectDescription.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js +44 -40
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js +82 -86
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectResource.js +55 -61
- package/dist/resource/shader/reflection/Tr2EffectResource.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js +49 -45
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js +25 -30
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2Pass.js +30 -32
- package/dist/resource/shader/reflection/Tr2Pass.js.map +1 -1
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js +21 -26
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js.map +1 -1
- package/docs/formats/README.md +4 -0
- package/docs/formats/provenance.md +11 -3
- package/docs/reference/classes/formats.md +440 -0
- package/format-notices/dxbc/LICENSE +21 -0
- package/format-notices/dxbc/NOTICE +20 -0
- package/format-notices/hlsl/LICENSE +21 -0
- package/format-notices/hlsl/NOTICE +25 -0
- package/format-notices/webgl/LICENSE +21 -0
- package/format-notices/webgl/NOTICE +35 -0
- package/format-notices/webgpu/LICENSE +21 -0
- package/format-notices/webgpu/NOTICE +31 -0
- package/package.json +6 -1
- package/dist/resource/shader/portableValidation.js +0 -461
- package/dist/resource/shader/portableValidation.js.map +0 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
const RESOURCE_IDENTITY = /^sampled-resource:(\d+):(\d+)$/u;
|
|
2
|
+
const DETAIL_PARAMETER = /^Detail(\d+)Map$/u;
|
|
3
|
+
const SAMPLE_OPCODES = new Set(["sample_b"]);
|
|
4
|
+
function deepFreeze(value) {
|
|
5
|
+
if (!value || typeof value !== "object" || Object.isFrozen(value)) return value;
|
|
6
|
+
for (const entry of Object.values(value)) deepFreeze(entry);
|
|
7
|
+
return Object.freeze(value);
|
|
8
|
+
}
|
|
9
|
+
function bindingRegister(binding) {
|
|
10
|
+
return binding.range?.lowerBound ?? binding.registerIndex;
|
|
11
|
+
}
|
|
12
|
+
function bindingSpace(binding) {
|
|
13
|
+
return binding.range?.registerSpace ?? 0;
|
|
14
|
+
}
|
|
15
|
+
function bindingIdentity(binding) {
|
|
16
|
+
return `${binding.resourceKind}:${bindingSpace(binding)}:${bindingRegister(binding)}`;
|
|
17
|
+
}
|
|
18
|
+
function scopeIdentity(identity, stage) {
|
|
19
|
+
return `${identity}@${stage}`;
|
|
20
|
+
}
|
|
21
|
+
function normalizeInput(input, transformId, index) {
|
|
22
|
+
const parameter = input?.parameter;
|
|
23
|
+
const layer = input?.layer;
|
|
24
|
+
const identity = input?.identity;
|
|
25
|
+
const scoped = input?.scopeIdentity;
|
|
26
|
+
if (typeof parameter !== "string" || !parameter || !Number.isInteger(layer) || layer !== index || typeof identity !== "string" || !RESOURCE_IDENTITY.test(identity) || scoped !== `${identity}@fragment`) {
|
|
27
|
+
throw new Error(`WGSL resource transform ${transformId} has an invalid input at layer ${index}`);
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
parameter,
|
|
31
|
+
layer,
|
|
32
|
+
identity,
|
|
33
|
+
scopeIdentity: scoped
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function normalizeTransform(transform) {
|
|
37
|
+
const id = transform?.id;
|
|
38
|
+
if (typeof id !== "string" || !id || transform.version !== 1 || transform.kind !== "texture-2d-array" || typeof transform.layoutKey !== "string" || !transform.layoutKey || transform.stage !== "fragment" || !Array.isArray(transform.inputs) || transform.inputs.length < 2) {
|
|
39
|
+
throw new Error(`WGSL resource transform ${id || "<unknown>"} has an invalid texture-array contract`);
|
|
40
|
+
}
|
|
41
|
+
const inputs = transform.inputs.map((input, index) => normalizeInput(input, id, index));
|
|
42
|
+
const inputParameters = new Set(inputs.map(input => input.parameter));
|
|
43
|
+
const inputIdentities = new Set(inputs.map(input => input.identity));
|
|
44
|
+
if (inputParameters.size !== inputs.length || inputIdentities.size !== inputs.length) {
|
|
45
|
+
throw new Error(`WGSL resource transform ${id} contains duplicate inputs`);
|
|
46
|
+
}
|
|
47
|
+
const output = transform.output;
|
|
48
|
+
if (typeof output?.name !== "string" || !output.name || output.identity !== inputs[0].identity || output.scopeIdentity !== inputs[0].scopeIdentity || output.viewDimension !== "2d-array" || output.layerCount !== inputs.length || transform.representation !== "native-or-rgba8" || transform.missingLayer !== "reject") {
|
|
49
|
+
throw new Error(`WGSL resource transform ${id} has an invalid output contract`);
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
id,
|
|
53
|
+
version: 1,
|
|
54
|
+
kind: "texture-2d-array",
|
|
55
|
+
layoutKey: transform.layoutKey,
|
|
56
|
+
stage: "fragment",
|
|
57
|
+
inputs,
|
|
58
|
+
output: {
|
|
59
|
+
name: output.name,
|
|
60
|
+
identity: output.identity,
|
|
61
|
+
scopeIdentity: output.scopeIdentity,
|
|
62
|
+
viewDimension: "2d-array",
|
|
63
|
+
layerCount: output.layerCount
|
|
64
|
+
},
|
|
65
|
+
representation: "native-or-rgba8",
|
|
66
|
+
missingLayer: "reject"
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Validates and freezes the compiler-owned resource-transform plan.
|
|
72
|
+
*
|
|
73
|
+
* @param {object|null|undefined} value Candidate plan.
|
|
74
|
+
* @param {string|null} [layoutKey] Optional expected pass layout key.
|
|
75
|
+
* @returns {object|null} Canonical frozen plan, or null.
|
|
76
|
+
*/
|
|
77
|
+
function normalizeResourceTransformPlan(value, layoutKey = null) {
|
|
78
|
+
if (value === undefined || value === null) return null;
|
|
79
|
+
if (value?.format !== "CJS_WGSL_RESOURCE_TRANSFORM_PLAN" || value.formatVersion !== 1 || !Array.isArray(value.resourceTransforms) || !value.resourceTransforms.length) {
|
|
80
|
+
throw new TypeError("WGSL resource transform plan must be a non-empty version-1 document");
|
|
81
|
+
}
|
|
82
|
+
const resourceTransforms = value.resourceTransforms.map(normalizeTransform).sort((left, right) => left.id.localeCompare(right.id));
|
|
83
|
+
const ids = new Set();
|
|
84
|
+
for (const transform of resourceTransforms) {
|
|
85
|
+
if (ids.has(transform.id)) {
|
|
86
|
+
throw new Error(`WGSL resource transform plan contains duplicate id ${transform.id}`);
|
|
87
|
+
}
|
|
88
|
+
ids.add(transform.id);
|
|
89
|
+
if (layoutKey !== null && transform.layoutKey !== layoutKey) {
|
|
90
|
+
throw new Error(`WGSL resource transform ${transform.id} targets ${transform.layoutKey}, expected ${layoutKey}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return deepFreeze({
|
|
94
|
+
format: "CJS_WGSL_RESOURCE_TRANSFORM_PLAN",
|
|
95
|
+
formatVersion: 1,
|
|
96
|
+
resourceTransforms
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function bindingMatchesForOperand(program, resourceKind, operand) {
|
|
100
|
+
const candidates = program.bindings.filter(binding => binding.resourceKind === resourceKind);
|
|
101
|
+
const rangeId = operand?.resourceReference?.rangeId;
|
|
102
|
+
return Number.isInteger(rangeId) ? candidates.filter(binding => binding.range?.rangeId === rangeId) : candidates.filter(binding => bindingRegister(binding) === operand?.registerIndex);
|
|
103
|
+
}
|
|
104
|
+
function resolveBindingForOperand(program, resourceKind, operand) {
|
|
105
|
+
const matches = bindingMatchesForOperand(program, resourceKind, operand);
|
|
106
|
+
if (matches.length !== 1) return null;
|
|
107
|
+
const binding = matches[0];
|
|
108
|
+
const absolute = operand?.resourceReference?.absoluteIndex;
|
|
109
|
+
if (operand?.typeName !== (resourceKind === "sampler" ? "sampler" : "resource") || (operand.modifierName ?? "none") !== "none" || (operand.minPrecisionName ?? "default") !== "default" || operand.nonUniform || operand.indices?.some(index => index?.relative) || operand.resourceReference?.nonUniform || absolute?.relative || absolute !== undefined && (absolute?.values?.length !== 1 || absolute.values[0] !== bindingRegister(binding))) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
return binding;
|
|
113
|
+
}
|
|
114
|
+
function operandFingerprint(operand) {
|
|
115
|
+
return JSON.stringify({
|
|
116
|
+
typeName: operand?.typeName ?? null,
|
|
117
|
+
selectionModeName: operand?.selectionModeName ?? null,
|
|
118
|
+
mask: operand?.mask ?? "",
|
|
119
|
+
swizzle: operand?.swizzle ?? "",
|
|
120
|
+
selected: operand?.selected ?? "",
|
|
121
|
+
modifierName: operand?.modifierName ?? "none",
|
|
122
|
+
minPrecisionName: operand?.minPrecisionName ?? "default",
|
|
123
|
+
registerIndex: operand?.registerIndex ?? null,
|
|
124
|
+
indices: (operand?.indices || []).map(index => ({
|
|
125
|
+
values: index?.values || [],
|
|
126
|
+
relative: index?.relative ?? null
|
|
127
|
+
})),
|
|
128
|
+
immediateValues: (operand?.immediateValues || []).map(entry => entry?.uint32)
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function semanticResource(binding) {
|
|
132
|
+
if (binding?.kind !== "resource") return null;
|
|
133
|
+
const parameter = binding.metadataName ?? binding.carbon?.name;
|
|
134
|
+
if (typeof parameter !== "string" || !parameter) return null;
|
|
135
|
+
return {
|
|
136
|
+
parameter,
|
|
137
|
+
registerIndex: binding.registerIndex,
|
|
138
|
+
registerSpace: binding.registerSpace ?? 0,
|
|
139
|
+
arrayElements: binding.arrayCount ?? binding.carbon?.arrayElements,
|
|
140
|
+
type: binding.carbon?.type,
|
|
141
|
+
isSRGB: binding.carbon?.isSRGB
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function rejectCandidate() {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Recognizes the exact Carbon Detail-map sample family and builds a late
|
|
150
|
+
* physical texture-array overlay. The source IR remains unchanged.
|
|
151
|
+
*
|
|
152
|
+
* @param {Array<{ir: object, semanticBindings: object[]}>} entries Pass stages.
|
|
153
|
+
* @param {object} options Planner options.
|
|
154
|
+
* @param {string} options.layoutKey Canonical pass key.
|
|
155
|
+
* @returns {object|null} Frozen transform plan, or null when proof is absent.
|
|
156
|
+
*/
|
|
157
|
+
function buildResourceTransformPlan(entries, options = {}) {
|
|
158
|
+
if (!Array.isArray(entries) || !entries.length) {
|
|
159
|
+
throw new TypeError("WGSL resource transform planning expects pass stage entries");
|
|
160
|
+
}
|
|
161
|
+
const layoutKey = options.layoutKey;
|
|
162
|
+
if (typeof layoutKey !== "string" || !layoutKey) {
|
|
163
|
+
throw new TypeError("WGSL resource transform planning requires a layoutKey");
|
|
164
|
+
}
|
|
165
|
+
const fragments = entries.filter(entry => entry?.ir?.stage === "pixel");
|
|
166
|
+
if (fragments.length !== 1) return null;
|
|
167
|
+
const {
|
|
168
|
+
ir: program
|
|
169
|
+
} = fragments[0];
|
|
170
|
+
if (program?.format !== "CJS_SHADER_IR" || program.formatVersion !== 1 || !Array.isArray(fragments[0].semanticBindings)) {
|
|
171
|
+
throw new TypeError("WGSL resource transform planning requires version-1 IR and semantic bindings");
|
|
172
|
+
}
|
|
173
|
+
const semanticResources = fragments[0].semanticBindings.map(semanticResource).filter(Boolean);
|
|
174
|
+
const detailResources = semanticResources.filter(resource => DETAIL_PARAMETER.test(resource.parameter));
|
|
175
|
+
if (!detailResources.length) return null;
|
|
176
|
+
const byName = new Map();
|
|
177
|
+
for (const resource of detailResources) {
|
|
178
|
+
if (byName.has(resource.parameter)) return rejectCandidate();
|
|
179
|
+
byName.set(resource.parameter, resource);
|
|
180
|
+
}
|
|
181
|
+
const hasThird = byName.has("Detail3Map");
|
|
182
|
+
const parameters = hasThird ? ["Detail1Map", "Detail2Map", "Detail3Map"] : ["Detail1Map", "Detail2Map"];
|
|
183
|
+
if (byName.size !== parameters.length || parameters.some(parameter => !byName.has(parameter))) {
|
|
184
|
+
return rejectCandidate();
|
|
185
|
+
}
|
|
186
|
+
const sources = [];
|
|
187
|
+
for (const parameter of parameters) {
|
|
188
|
+
const semantic = byName.get(parameter);
|
|
189
|
+
if (!Number.isInteger(semantic.registerIndex) || semantic.registerIndex < 0 || !Number.isInteger(semantic.registerSpace) || semantic.registerSpace < 0 || semantic.arrayElements !== 1 || semantic.type !== 2 || semantic.isSRGB !== false) {
|
|
190
|
+
return rejectCandidate();
|
|
191
|
+
}
|
|
192
|
+
const matches = program.bindings.filter(binding => binding.resourceKind === "sampled-resource" && bindingSpace(binding) === semantic.registerSpace && bindingRegister(binding) === semantic.registerIndex);
|
|
193
|
+
if (matches.length !== 1) return rejectCandidate();
|
|
194
|
+
const binding = matches[0];
|
|
195
|
+
const returns = binding.returnType?.returnTypeNames || [];
|
|
196
|
+
if (binding.resourceDimension !== "texture2d" || binding.structureStride !== null || binding.range?.unbounded || binding.range?.registerCount !== 1 || returns.length !== 4 || returns.some(entry => entry !== "float")) {
|
|
197
|
+
return rejectCandidate();
|
|
198
|
+
}
|
|
199
|
+
sources.push({
|
|
200
|
+
parameter,
|
|
201
|
+
semantic,
|
|
202
|
+
binding,
|
|
203
|
+
identity: bindingIdentity(binding)
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
if (sources.some((source, index) => index > 0 && (source.semantic.registerSpace !== sources[0].semantic.registerSpace || source.semantic.registerIndex <= sources[index - 1].semantic.registerIndex))) {
|
|
207
|
+
return rejectCandidate();
|
|
208
|
+
}
|
|
209
|
+
const sourceByIdentity = new Map(sources.map(source => [source.identity, source]));
|
|
210
|
+
const uses = new Map(sources.map(source => [source.identity, 0]));
|
|
211
|
+
let samplerIdentity = null;
|
|
212
|
+
let biasFingerprint = null;
|
|
213
|
+
for (const instruction of program.instructions) {
|
|
214
|
+
for (let operandIndex = 0; operandIndex < instruction.operands.length; operandIndex += 1) {
|
|
215
|
+
const operand = instruction.operands[operandIndex];
|
|
216
|
+
if (operand?.typeName !== "resource") continue;
|
|
217
|
+
const binding = resolveBindingForOperand(program, "sampled-resource", operand);
|
|
218
|
+
if (!binding) {
|
|
219
|
+
const unresolvedCandidate = bindingMatchesForOperand(program, "sampled-resource", operand).some(candidate => sourceByIdentity.has(bindingIdentity(candidate)));
|
|
220
|
+
if (unresolvedCandidate) return rejectCandidate();
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const identity = bindingIdentity(binding);
|
|
224
|
+
if (!sourceByIdentity.has(identity)) continue;
|
|
225
|
+
if (!SAMPLE_OPCODES.has(instruction.opcodeName) || operandIndex !== 2 || instruction.extensions?.some(extension => extension.typeName === "sample_controls") || instruction.operands.length !== 5) {
|
|
226
|
+
return rejectCandidate();
|
|
227
|
+
}
|
|
228
|
+
const sampler = resolveBindingForOperand(program, "sampler", instruction.operands[3]);
|
|
229
|
+
if (!sampler) return rejectCandidate();
|
|
230
|
+
const currentSamplerIdentity = bindingIdentity(sampler);
|
|
231
|
+
const currentBiasFingerprint = operandFingerprint(instruction.operands[4]);
|
|
232
|
+
if (samplerIdentity !== null && samplerIdentity !== currentSamplerIdentity || biasFingerprint !== null && biasFingerprint !== currentBiasFingerprint) {
|
|
233
|
+
return rejectCandidate();
|
|
234
|
+
}
|
|
235
|
+
samplerIdentity = currentSamplerIdentity;
|
|
236
|
+
biasFingerprint = currentBiasFingerprint;
|
|
237
|
+
uses.set(identity, uses.get(identity) + 1);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (samplerIdentity === null || Array.from(uses.values()).some(count => count < 1)) {
|
|
241
|
+
return rejectCandidate();
|
|
242
|
+
}
|
|
243
|
+
const inputs = sources.map((source, layer) => ({
|
|
244
|
+
parameter: source.parameter,
|
|
245
|
+
layer,
|
|
246
|
+
identity: source.identity,
|
|
247
|
+
scopeIdentity: scopeIdentity(source.identity, "fragment")
|
|
248
|
+
}));
|
|
249
|
+
const first = inputs[0];
|
|
250
|
+
const id = `${layoutKey}:detail-map-array:${first.identity}`;
|
|
251
|
+
return normalizeResourceTransformPlan({
|
|
252
|
+
format: "CJS_WGSL_RESOURCE_TRANSFORM_PLAN",
|
|
253
|
+
formatVersion: 1,
|
|
254
|
+
resourceTransforms: [{
|
|
255
|
+
id,
|
|
256
|
+
version: 1,
|
|
257
|
+
kind: "texture-2d-array",
|
|
258
|
+
layoutKey,
|
|
259
|
+
stage: "fragment",
|
|
260
|
+
inputs,
|
|
261
|
+
output: {
|
|
262
|
+
name: "DetailMapArray",
|
|
263
|
+
identity: first.identity,
|
|
264
|
+
scopeIdentity: first.scopeIdentity,
|
|
265
|
+
viewDimension: "2d-array",
|
|
266
|
+
layerCount: inputs.length
|
|
267
|
+
},
|
|
268
|
+
representation: "native-or-rgba8",
|
|
269
|
+
missingLayer: "reject"
|
|
270
|
+
}]
|
|
271
|
+
}, layoutKey);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export { buildResourceTransformPlan, normalizeResourceTransformPlan };
|
|
275
|
+
//# sourceMappingURL=buildResourceTransformPlan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildResourceTransformPlan.js","sources":["../../../../../../src/formats/webgpu/core/wgsl/buildResourceTransformPlan.js"],"sourcesContent":["const RESOURCE_IDENTITY = /^sampled-resource:(\\d+):(\\d+)$/u;\nconst DETAIL_PARAMETER = /^Detail(\\d+)Map$/u;\nconst SAMPLE_OPCODES = new Set([ \"sample_b\" ]);\n\nfunction deepFreeze(value)\n{\n if (!value || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n for (const entry of Object.values(value)) deepFreeze(entry);\n return Object.freeze(value);\n}\n\nfunction bindingRegister(binding)\n{\n return binding.range?.lowerBound ?? binding.registerIndex;\n}\n\nfunction bindingSpace(binding)\n{\n return binding.range?.registerSpace ?? 0;\n}\n\nfunction bindingIdentity(binding)\n{\n return `${binding.resourceKind}:${bindingSpace(binding)}:${bindingRegister(binding)}`;\n}\n\nfunction scopeIdentity(identity, stage)\n{\n return `${identity}@${stage}`;\n}\n\nfunction normalizeInput(input, transformId, index)\n{\n const parameter = input?.parameter;\n const layer = input?.layer;\n const identity = input?.identity;\n const scoped = input?.scopeIdentity;\n if (typeof parameter !== \"string\" || !parameter\n || !Number.isInteger(layer) || layer !== index\n || typeof identity !== \"string\" || !RESOURCE_IDENTITY.test(identity)\n || scoped !== `${identity}@fragment`)\n {\n throw new Error(`WGSL resource transform ${transformId} has an invalid input at layer ${index}`);\n }\n return { parameter, layer, identity, scopeIdentity: scoped };\n}\n\nfunction normalizeTransform(transform)\n{\n const id = transform?.id;\n if (typeof id !== \"string\" || !id\n || transform.version !== 1\n || transform.kind !== \"texture-2d-array\"\n || typeof transform.layoutKey !== \"string\" || !transform.layoutKey\n || transform.stage !== \"fragment\"\n || !Array.isArray(transform.inputs)\n || transform.inputs.length < 2)\n {\n throw new Error(`WGSL resource transform ${id || \"<unknown>\"} has an invalid texture-array contract`);\n }\n const inputs = transform.inputs.map((input, index) => normalizeInput(input, id, index));\n const inputParameters = new Set(inputs.map((input) => input.parameter));\n const inputIdentities = new Set(inputs.map((input) => input.identity));\n if (inputParameters.size !== inputs.length || inputIdentities.size !== inputs.length)\n {\n throw new Error(`WGSL resource transform ${id} contains duplicate inputs`);\n }\n const output = transform.output;\n if (typeof output?.name !== \"string\" || !output.name\n || output.identity !== inputs[0].identity\n || output.scopeIdentity !== inputs[0].scopeIdentity\n || output.viewDimension !== \"2d-array\"\n || output.layerCount !== inputs.length\n || transform.representation !== \"native-or-rgba8\"\n || transform.missingLayer !== \"reject\")\n {\n throw new Error(`WGSL resource transform ${id} has an invalid output contract`);\n }\n return {\n id,\n version: 1,\n kind: \"texture-2d-array\",\n layoutKey: transform.layoutKey,\n stage: \"fragment\",\n inputs,\n output: {\n name: output.name,\n identity: output.identity,\n scopeIdentity: output.scopeIdentity,\n viewDimension: \"2d-array\",\n layerCount: output.layerCount\n },\n representation: \"native-or-rgba8\",\n missingLayer: \"reject\"\n };\n}\n\n/**\n * Validates and freezes the compiler-owned resource-transform plan.\n *\n * @param {object|null|undefined} value Candidate plan.\n * @param {string|null} [layoutKey] Optional expected pass layout key.\n * @returns {object|null} Canonical frozen plan, or null.\n */\nexport function normalizeResourceTransformPlan(value, layoutKey = null)\n{\n if (value === undefined || value === null) return null;\n if (value?.format !== \"CJS_WGSL_RESOURCE_TRANSFORM_PLAN\"\n || value.formatVersion !== 1\n || !Array.isArray(value.resourceTransforms)\n || !value.resourceTransforms.length)\n {\n throw new TypeError(\"WGSL resource transform plan must be a non-empty version-1 document\");\n }\n const resourceTransforms = value.resourceTransforms.map(normalizeTransform)\n .sort((left, right) => left.id.localeCompare(right.id));\n const ids = new Set();\n for (const transform of resourceTransforms)\n {\n if (ids.has(transform.id))\n {\n throw new Error(`WGSL resource transform plan contains duplicate id ${transform.id}`);\n }\n ids.add(transform.id);\n if (layoutKey !== null && transform.layoutKey !== layoutKey)\n {\n throw new Error(`WGSL resource transform ${transform.id} targets ${transform.layoutKey}, expected ${layoutKey}`);\n }\n }\n return deepFreeze({\n format: \"CJS_WGSL_RESOURCE_TRANSFORM_PLAN\",\n formatVersion: 1,\n resourceTransforms\n });\n}\n\nfunction bindingMatchesForOperand(program, resourceKind, operand)\n{\n const candidates = program.bindings.filter((binding) =>\n binding.resourceKind === resourceKind);\n const rangeId = operand?.resourceReference?.rangeId;\n return Number.isInteger(rangeId)\n ? candidates.filter((binding) => binding.range?.rangeId === rangeId)\n : candidates.filter((binding) => bindingRegister(binding) === operand?.registerIndex);\n}\n\nfunction resolveBindingForOperand(program, resourceKind, operand)\n{\n const matches = bindingMatchesForOperand(program, resourceKind, operand);\n if (matches.length !== 1) return null;\n const binding = matches[0];\n const absolute = operand?.resourceReference?.absoluteIndex;\n if (operand?.typeName !== (resourceKind === \"sampler\" ? \"sampler\" : \"resource\")\n || (operand.modifierName ?? \"none\") !== \"none\"\n || (operand.minPrecisionName ?? \"default\") !== \"default\"\n || operand.nonUniform\n || operand.indices?.some((index) => index?.relative)\n || operand.resourceReference?.nonUniform\n || absolute?.relative\n || (absolute !== undefined\n && (absolute?.values?.length !== 1\n || absolute.values[0] !== bindingRegister(binding))))\n {\n return null;\n }\n return binding;\n}\n\nfunction operandFingerprint(operand)\n{\n return JSON.stringify({\n typeName: operand?.typeName ?? null,\n selectionModeName: operand?.selectionModeName ?? null,\n mask: operand?.mask ?? \"\",\n swizzle: operand?.swizzle ?? \"\",\n selected: operand?.selected ?? \"\",\n modifierName: operand?.modifierName ?? \"none\",\n minPrecisionName: operand?.minPrecisionName ?? \"default\",\n registerIndex: operand?.registerIndex ?? null,\n indices: (operand?.indices || []).map((index) => ({\n values: index?.values || [],\n relative: index?.relative ?? null\n })),\n immediateValues: (operand?.immediateValues || []).map((entry) => entry?.uint32)\n });\n}\n\nfunction semanticResource(binding)\n{\n if (binding?.kind !== \"resource\") return null;\n const parameter = binding.metadataName ?? binding.carbon?.name;\n if (typeof parameter !== \"string\" || !parameter) return null;\n return {\n parameter,\n registerIndex: binding.registerIndex,\n registerSpace: binding.registerSpace ?? 0,\n arrayElements: binding.arrayCount ?? binding.carbon?.arrayElements,\n type: binding.carbon?.type,\n isSRGB: binding.carbon?.isSRGB\n };\n}\n\nfunction rejectCandidate()\n{\n return null;\n}\n\n/**\n * Recognizes the exact Carbon Detail-map sample family and builds a late\n * physical texture-array overlay. The source IR remains unchanged.\n *\n * @param {Array<{ir: object, semanticBindings: object[]}>} entries Pass stages.\n * @param {object} options Planner options.\n * @param {string} options.layoutKey Canonical pass key.\n * @returns {object|null} Frozen transform plan, or null when proof is absent.\n */\nexport function buildResourceTransformPlan(entries, options = {})\n{\n if (!Array.isArray(entries) || !entries.length)\n {\n throw new TypeError(\"WGSL resource transform planning expects pass stage entries\");\n }\n const layoutKey = options.layoutKey;\n if (typeof layoutKey !== \"string\" || !layoutKey)\n {\n throw new TypeError(\"WGSL resource transform planning requires a layoutKey\");\n }\n const fragments = entries.filter((entry) => entry?.ir?.stage === \"pixel\");\n if (fragments.length !== 1) return null;\n const { ir: program } = fragments[0];\n if (program?.format !== \"CJS_SHADER_IR\" || program.formatVersion !== 1\n || !Array.isArray(fragments[0].semanticBindings))\n {\n throw new TypeError(\"WGSL resource transform planning requires version-1 IR and semantic bindings\");\n }\n const semanticResources = fragments[0].semanticBindings.map(semanticResource).filter(Boolean);\n const detailResources = semanticResources.filter((resource) => DETAIL_PARAMETER.test(resource.parameter));\n if (!detailResources.length) return null;\n const byName = new Map();\n for (const resource of detailResources)\n {\n if (byName.has(resource.parameter)) return rejectCandidate();\n byName.set(resource.parameter, resource);\n }\n const hasThird = byName.has(\"Detail3Map\");\n const parameters = hasThird\n ? [ \"Detail1Map\", \"Detail2Map\", \"Detail3Map\" ]\n : [ \"Detail1Map\", \"Detail2Map\" ];\n if (byName.size !== parameters.length\n || parameters.some((parameter) => !byName.has(parameter)))\n {\n return rejectCandidate();\n }\n\n const sources = [];\n for (const parameter of parameters)\n {\n const semantic = byName.get(parameter);\n if (!Number.isInteger(semantic.registerIndex) || semantic.registerIndex < 0\n || !Number.isInteger(semantic.registerSpace) || semantic.registerSpace < 0\n || semantic.arrayElements !== 1\n || semantic.type !== 2\n || semantic.isSRGB !== false)\n {\n return rejectCandidate();\n }\n const matches = program.bindings.filter((binding) =>\n binding.resourceKind === \"sampled-resource\"\n && bindingSpace(binding) === semantic.registerSpace\n && bindingRegister(binding) === semantic.registerIndex);\n if (matches.length !== 1) return rejectCandidate();\n const binding = matches[0];\n const returns = binding.returnType?.returnTypeNames || [];\n if (binding.resourceDimension !== \"texture2d\"\n || binding.structureStride !== null\n || binding.range?.unbounded\n || binding.range?.registerCount !== 1\n || returns.length !== 4\n || returns.some((entry) => entry !== \"float\"))\n {\n return rejectCandidate();\n }\n sources.push({ parameter, semantic, binding, identity: bindingIdentity(binding) });\n }\n if (sources.some((source, index) =>\n index > 0\n && (source.semantic.registerSpace !== sources[0].semantic.registerSpace\n || source.semantic.registerIndex <= sources[index - 1].semantic.registerIndex)))\n {\n return rejectCandidate();\n }\n\n const sourceByIdentity = new Map(sources.map((source) => [ source.identity, source ]));\n const uses = new Map(sources.map((source) => [ source.identity, 0 ]));\n let samplerIdentity = null;\n let biasFingerprint = null;\n for (const instruction of program.instructions)\n {\n for (let operandIndex = 0; operandIndex < instruction.operands.length; operandIndex += 1)\n {\n const operand = instruction.operands[operandIndex];\n if (operand?.typeName !== \"resource\") continue;\n const binding = resolveBindingForOperand(program, \"sampled-resource\", operand);\n if (!binding)\n {\n const unresolvedCandidate = bindingMatchesForOperand(\n program,\n \"sampled-resource\",\n operand\n ).some((candidate) =>\n sourceByIdentity.has(bindingIdentity(candidate)));\n if (unresolvedCandidate) return rejectCandidate();\n continue;\n }\n const identity = bindingIdentity(binding);\n if (!sourceByIdentity.has(identity)) continue;\n if (!SAMPLE_OPCODES.has(instruction.opcodeName)\n || operandIndex !== 2\n || instruction.extensions?.some((extension) =>\n extension.typeName === \"sample_controls\")\n || instruction.operands.length !== 5)\n {\n return rejectCandidate();\n }\n const sampler = resolveBindingForOperand(program, \"sampler\", instruction.operands[3]);\n if (!sampler) return rejectCandidate();\n const currentSamplerIdentity = bindingIdentity(sampler);\n const currentBiasFingerprint = operandFingerprint(instruction.operands[4]);\n if ((samplerIdentity !== null && samplerIdentity !== currentSamplerIdentity)\n || (biasFingerprint !== null && biasFingerprint !== currentBiasFingerprint))\n {\n return rejectCandidate();\n }\n samplerIdentity = currentSamplerIdentity;\n biasFingerprint = currentBiasFingerprint;\n uses.set(identity, uses.get(identity) + 1);\n }\n }\n if (samplerIdentity === null || Array.from(uses.values()).some((count) => count < 1))\n {\n return rejectCandidate();\n }\n\n const inputs = sources.map((source, layer) => ({\n parameter: source.parameter,\n layer,\n identity: source.identity,\n scopeIdentity: scopeIdentity(source.identity, \"fragment\")\n }));\n const first = inputs[0];\n const id = `${layoutKey}:detail-map-array:${first.identity}`;\n return normalizeResourceTransformPlan({\n format: \"CJS_WGSL_RESOURCE_TRANSFORM_PLAN\",\n formatVersion: 1,\n resourceTransforms: [ {\n id,\n version: 1,\n kind: \"texture-2d-array\",\n layoutKey,\n stage: \"fragment\",\n inputs,\n output: {\n name: \"DetailMapArray\",\n identity: first.identity,\n scopeIdentity: first.scopeIdentity,\n viewDimension: \"2d-array\",\n layerCount: inputs.length\n },\n representation: \"native-or-rgba8\",\n missingLayer: \"reject\"\n } ]\n }, layoutKey);\n}\n"],"names":["RESOURCE_IDENTITY","DETAIL_PARAMETER","SAMPLE_OPCODES","Set","deepFreeze","value","Object","isFrozen","entry","values","freeze","bindingRegister","binding","range","lowerBound","registerIndex","bindingSpace","registerSpace","bindingIdentity","resourceKind","scopeIdentity","identity","stage","normalizeInput","input","transformId","index","parameter","layer","scoped","Number","isInteger","test","Error","normalizeTransform","transform","id","version","kind","layoutKey","Array","isArray","inputs","length","map","inputParameters","inputIdentities","size","output","name","viewDimension","layerCount","representation","missingLayer","normalizeResourceTransformPlan","undefined","format","formatVersion","resourceTransforms","TypeError","sort","left","right","localeCompare","ids","has","add","bindingMatchesForOperand","program","operand","candidates","bindings","filter","rangeId","resourceReference","resolveBindingForOperand","matches","absolute","absoluteIndex","typeName","modifierName","minPrecisionName","nonUniform","indices","some","relative","operandFingerprint","JSON","stringify","selectionModeName","mask","swizzle","selected","immediateValues","uint32","semanticResource","metadataName","carbon","arrayElements","arrayCount","type","isSRGB","rejectCandidate","buildResourceTransformPlan","entries","options","fragments","ir","semanticBindings","semanticResources","Boolean","detailResources","resource","byName","Map","set","hasThird","parameters","sources","semantic","get","returns","returnType","returnTypeNames","resourceDimension","structureStride","unbounded","registerCount","push","source","sourceByIdentity","uses","samplerIdentity","biasFingerprint","instruction","instructions","operandIndex","operands","unresolvedCandidate","candidate","opcodeName","extensions","extension","sampler","currentSamplerIdentity","currentBiasFingerprint","from","count","first"],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { lowerBindingLayout } from './lowerBindingLayout.js';
|
|
2
|
+
import { normalizeResourceTransformPlan } from './buildResourceTransformPlan.js';
|
|
3
|
+
import { particleClearSignedAtomicLayoutPolicy } from './lowerParticleClearComputePrograms.js';
|
|
4
|
+
import { particleEmitSignedAtomicLayoutPolicy } from './lowerParticleEmitComputeProgram.js';
|
|
5
|
+
|
|
6
|
+
const KIND_ORDER = Object.freeze({
|
|
7
|
+
"uniform-buffer": 0,
|
|
8
|
+
"sampled-resource": 1,
|
|
9
|
+
sampler: 2,
|
|
10
|
+
"storage-resource": 3
|
|
11
|
+
});
|
|
12
|
+
const STAGE_VISIBILITY = Object.freeze({
|
|
13
|
+
vertex: "vertex",
|
|
14
|
+
pixel: "fragment",
|
|
15
|
+
compute: "compute"
|
|
16
|
+
});
|
|
17
|
+
const STAGE_ORDER = Object.freeze({
|
|
18
|
+
vertex: 0,
|
|
19
|
+
fragment: 1,
|
|
20
|
+
compute: 2
|
|
21
|
+
});
|
|
22
|
+
const IDENTITY_PATTERN = /^(uniform-buffer|sampled-resource|sampler|storage-resource):\d+:\d+$/u;
|
|
23
|
+
function identity(binding) {
|
|
24
|
+
return `${binding.resourceKind}:${binding.registerSpace}:${binding.registerIndex}`;
|
|
25
|
+
}
|
|
26
|
+
function portableBinding(binding) {
|
|
27
|
+
const d3dIdentity = identity(binding);
|
|
28
|
+
return {
|
|
29
|
+
identity: d3dIdentity,
|
|
30
|
+
resourceKind: binding.resourceKind,
|
|
31
|
+
generatedSymbol: binding.generatedSymbol,
|
|
32
|
+
registerSpace: binding.registerSpace,
|
|
33
|
+
registerIndex: binding.registerIndex,
|
|
34
|
+
type: binding.type,
|
|
35
|
+
...(typeof binding.transformId === "string" ? {
|
|
36
|
+
transformId: binding.transformId,
|
|
37
|
+
arrayLayerCount: binding.arrayLayerCount
|
|
38
|
+
} : {}),
|
|
39
|
+
...(Number.isInteger(binding.structureStride) ? {
|
|
40
|
+
structureStride: binding.structureStride
|
|
41
|
+
} : {}),
|
|
42
|
+
...(binding.buffer ? {
|
|
43
|
+
buffer: binding.buffer
|
|
44
|
+
} : {}),
|
|
45
|
+
...(binding.texture ? {
|
|
46
|
+
texture: binding.texture
|
|
47
|
+
} : {}),
|
|
48
|
+
...(binding.sampler ? {
|
|
49
|
+
sampler: binding.sampler
|
|
50
|
+
} : {})
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function fingerprint(binding) {
|
|
54
|
+
return JSON.stringify(binding);
|
|
55
|
+
}
|
|
56
|
+
function deepFreeze(value) {
|
|
57
|
+
if (!value || typeof value !== "object" || Object.isFrozen(value)) return value;
|
|
58
|
+
for (const entry of Object.values(value)) deepFreeze(entry);
|
|
59
|
+
return Object.freeze(value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Builds one deterministic numeric binding plan for all shader stages in a
|
|
64
|
+
* pass. Unshared D3D tuples remain stage-scoped unless the caller explicitly
|
|
65
|
+
* confirms that compatible declarations describe one shared resource.
|
|
66
|
+
*
|
|
67
|
+
* @param {object[]} programs Complete CJS shader IR stage set for one effect pass.
|
|
68
|
+
* @param {object} [options] Explicit pass-level identity policy.
|
|
69
|
+
* @param {string[]} [options.sharedIdentities] D3D identities confirmed by
|
|
70
|
+
* pass metadata/CjsLibrary to represent one resource across stages.
|
|
71
|
+
* @param {object|null} [options.effectProfileProof] Opaque exact-effect proof.
|
|
72
|
+
* @returns {object} Frozen pass-global binding plan.
|
|
73
|
+
*/
|
|
74
|
+
function buildWgslBindingPlan(programs, options = {}) {
|
|
75
|
+
if (!Array.isArray(programs) || !programs.length) {
|
|
76
|
+
throw new TypeError("BuildWgslBindingPlan expects at least one CJS shader IR program");
|
|
77
|
+
}
|
|
78
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
79
|
+
throw new TypeError("BuildWgslBindingPlan options must be an object");
|
|
80
|
+
}
|
|
81
|
+
const requestedShared = options.sharedIdentities === undefined ? [] : options.sharedIdentities;
|
|
82
|
+
if (!Array.isArray(requestedShared) || requestedShared.some(entry => typeof entry !== "string" || !IDENTITY_PATTERN.test(entry)) || new Set(requestedShared).size !== requestedShared.length) {
|
|
83
|
+
throw new TypeError("BuildWgslBindingPlan sharedIdentities must contain unique D3D resource identities");
|
|
84
|
+
}
|
|
85
|
+
const sharedIdentities = new Set(requestedShared);
|
|
86
|
+
const resourceTransformPlan = normalizeResourceTransformPlan(options.resourceTransformPlan);
|
|
87
|
+
const identities = new Map();
|
|
88
|
+
const programStages = new Set();
|
|
89
|
+
for (const [index, program] of programs.entries()) {
|
|
90
|
+
if (program?.format !== "CJS_SHADER_IR" || program.formatVersion !== 1) {
|
|
91
|
+
throw new TypeError(`BuildWgslBindingPlan program ${index} is not CJS_SHADER_IR version 1`);
|
|
92
|
+
}
|
|
93
|
+
const stage = STAGE_VISIBILITY[program.stage];
|
|
94
|
+
if (!stage) {
|
|
95
|
+
throw new Error(`BuildWgslBindingPlan program ${index} has unsupported stage ${program.stage || "unknown"}`);
|
|
96
|
+
}
|
|
97
|
+
if (programStages.has(stage)) {
|
|
98
|
+
throw new Error(`BuildWgslBindingPlan contains multiple ${stage} programs for one pass`);
|
|
99
|
+
}
|
|
100
|
+
programStages.add(stage);
|
|
101
|
+
const layoutPolicy = particleClearSignedAtomicLayoutPolicy(program, options.effectProfileProof ?? null) ?? particleEmitSignedAtomicLayoutPolicy(program);
|
|
102
|
+
for (const binding of lowerBindingLayout(program, null, layoutPolicy, resourceTransformPlan)) {
|
|
103
|
+
const key = identity(binding);
|
|
104
|
+
const entry = portableBinding(binding);
|
|
105
|
+
if (!identities.has(key)) identities.set(key, []);
|
|
106
|
+
identities.get(key).push({
|
|
107
|
+
binding: entry,
|
|
108
|
+
stage
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (programStages.has("compute") && programStages.size !== 1) {
|
|
113
|
+
throw new Error("BuildWgslBindingPlan cannot mix compute and render programs in one pass");
|
|
114
|
+
}
|
|
115
|
+
const bindings = [];
|
|
116
|
+
for (const [key, occurrences] of identities) {
|
|
117
|
+
const stages = occurrences.map(entry => entry.stage).sort((left, right) => STAGE_ORDER[left] - STAGE_ORDER[right]);
|
|
118
|
+
if (sharedIdentities.has(key)) {
|
|
119
|
+
if (occurrences.length < 2) {
|
|
120
|
+
throw new Error(`WGSL shared identity ${key} does not occur in multiple stages`);
|
|
121
|
+
}
|
|
122
|
+
const expected = fingerprint(occurrences[0].binding);
|
|
123
|
+
if (occurrences.some(entry => fingerprint(entry.binding) !== expected)) {
|
|
124
|
+
throw new Error(`WGSL shared identity ${key} has incompatible stage declarations`);
|
|
125
|
+
}
|
|
126
|
+
bindings.push({
|
|
127
|
+
...occurrences[0].binding,
|
|
128
|
+
scopeIdentity: key,
|
|
129
|
+
stages
|
|
130
|
+
});
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
for (const occurrence of occurrences) {
|
|
134
|
+
bindings.push({
|
|
135
|
+
...occurrence.binding,
|
|
136
|
+
scopeIdentity: `${key}@${occurrence.stage}`,
|
|
137
|
+
stages: [occurrence.stage]
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
for (const key of sharedIdentities) {
|
|
142
|
+
if (!identities.has(key)) throw new Error(`WGSL shared identity ${key} does not occur in the pass`);
|
|
143
|
+
}
|
|
144
|
+
bindings.sort((left, right) => left.registerSpace - right.registerSpace || (KIND_ORDER[left.resourceKind] ?? 99) - (KIND_ORDER[right.resourceKind] ?? 99) || left.registerIndex - right.registerIndex || (STAGE_ORDER[left.stages[0]] ?? 99) - (STAGE_ORDER[right.stages[0]] ?? 99) || left.generatedSymbol.localeCompare(right.generatedSymbol) || left.scopeIdentity.localeCompare(right.scopeIdentity));
|
|
145
|
+
const plannedBindings = bindings.map((binding, bindingIndex) => ({
|
|
146
|
+
...binding,
|
|
147
|
+
group: 0,
|
|
148
|
+
binding: bindingIndex
|
|
149
|
+
}));
|
|
150
|
+
|
|
151
|
+
// WebGPU pipeline creation requires the vertex output and fragment input
|
|
152
|
+
// interpolation attributes at one location to MATCH, and interpolation is
|
|
153
|
+
// declared only on the fragment side in DXBC (dcl_input_ps). Record the
|
|
154
|
+
// non-default modes here so the vertex module can mirror them.
|
|
155
|
+
const varyingInterpolation = {};
|
|
156
|
+
for (const program of programs) {
|
|
157
|
+
if (program.stage !== "pixel") continue;
|
|
158
|
+
for (const declaration of program.declarations || []) {
|
|
159
|
+
if (declaration.opcodeName !== "dcl_input_ps") continue;
|
|
160
|
+
if (declaration.data?.interpolationModeName === "linear_noperspective") {
|
|
161
|
+
varyingInterpolation[declaration.data.registerIndex] = "linear";
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return deepFreeze({
|
|
166
|
+
format: "CJS_WGSL_BINDING_PLAN",
|
|
167
|
+
formatVersion: resourceTransformPlan ? 3 : 2,
|
|
168
|
+
...(sharedIdentities.size ? {
|
|
169
|
+
sharedIdentities: Object.freeze([...sharedIdentities].sort())
|
|
170
|
+
} : {}),
|
|
171
|
+
...(Object.keys(varyingInterpolation).length ? {
|
|
172
|
+
varyingInterpolation
|
|
173
|
+
} : {}),
|
|
174
|
+
...(resourceTransformPlan ? {
|
|
175
|
+
resourceTransforms: resourceTransformPlan.resourceTransforms
|
|
176
|
+
} : {}),
|
|
177
|
+
bindings: plannedBindings
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export { buildWgslBindingPlan };
|
|
182
|
+
//# sourceMappingURL=buildWgslBindingPlan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildWgslBindingPlan.js","sources":["../../../../../../src/formats/webgpu/core/wgsl/buildWgslBindingPlan.js"],"sourcesContent":["import { lowerBindingLayout } from \"./lowerBindingLayout.js\";\nimport { normalizeResourceTransformPlan } from \"./buildResourceTransformPlan.js\";\nimport {\n particleClearSignedAtomicLayoutPolicy\n} from \"./lowerParticleClearComputePrograms.js\";\nimport {\n particleEmitSignedAtomicLayoutPolicy\n} from \"./lowerParticleEmitComputeProgram.js\";\n\nconst KIND_ORDER = Object.freeze({\n \"uniform-buffer\": 0,\n \"sampled-resource\": 1,\n sampler: 2,\n \"storage-resource\": 3\n});\n\nconst STAGE_VISIBILITY = Object.freeze({ vertex: \"vertex\", pixel: \"fragment\", compute: \"compute\" });\nconst STAGE_ORDER = Object.freeze({ vertex: 0, fragment: 1, compute: 2 });\nconst IDENTITY_PATTERN = /^(uniform-buffer|sampled-resource|sampler|storage-resource):\\d+:\\d+$/u;\n\nfunction identity(binding)\n{\n return `${binding.resourceKind}:${binding.registerSpace}:${binding.registerIndex}`;\n}\n\nfunction portableBinding(binding)\n{\n const d3dIdentity = identity(binding);\n return {\n identity: d3dIdentity,\n resourceKind: binding.resourceKind,\n generatedSymbol: binding.generatedSymbol,\n registerSpace: binding.registerSpace,\n registerIndex: binding.registerIndex,\n type: binding.type,\n ...(typeof binding.transformId === \"string\"\n ? {\n transformId: binding.transformId,\n arrayLayerCount: binding.arrayLayerCount\n }\n : {}),\n ...(Number.isInteger(binding.structureStride) ? { structureStride: binding.structureStride } : {}),\n ...(binding.buffer ? { buffer: binding.buffer } : {}),\n ...(binding.texture ? { texture: binding.texture } : {}),\n ...(binding.sampler ? { sampler: binding.sampler } : {})\n };\n}\n\nfunction fingerprint(binding)\n{\n return JSON.stringify(binding);\n}\n\nfunction deepFreeze(value)\n{\n if (!value || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n for (const entry of Object.values(value)) deepFreeze(entry);\n return Object.freeze(value);\n}\n\n/**\n * Builds one deterministic numeric binding plan for all shader stages in a\n * pass. Unshared D3D tuples remain stage-scoped unless the caller explicitly\n * confirms that compatible declarations describe one shared resource.\n *\n * @param {object[]} programs Complete CJS shader IR stage set for one effect pass.\n * @param {object} [options] Explicit pass-level identity policy.\n * @param {string[]} [options.sharedIdentities] D3D identities confirmed by\n * pass metadata/CjsLibrary to represent one resource across stages.\n * @param {object|null} [options.effectProfileProof] Opaque exact-effect proof.\n * @returns {object} Frozen pass-global binding plan.\n */\nexport function buildWgslBindingPlan(programs, options = {})\n{\n if (!Array.isArray(programs) || !programs.length)\n {\n throw new TypeError(\"BuildWgslBindingPlan expects at least one CJS shader IR program\");\n }\n if (!options || typeof options !== \"object\" || Array.isArray(options))\n {\n throw new TypeError(\"BuildWgslBindingPlan options must be an object\");\n }\n const requestedShared = options.sharedIdentities === undefined ? [] : options.sharedIdentities;\n if (!Array.isArray(requestedShared)\n || requestedShared.some((entry) => typeof entry !== \"string\" || !IDENTITY_PATTERN.test(entry))\n || new Set(requestedShared).size !== requestedShared.length)\n {\n throw new TypeError(\"BuildWgslBindingPlan sharedIdentities must contain unique D3D resource identities\");\n }\n const sharedIdentities = new Set(requestedShared);\n const resourceTransformPlan = normalizeResourceTransformPlan(\n options.resourceTransformPlan\n );\n const identities = new Map();\n const programStages = new Set();\n for (const [ index, program ] of programs.entries())\n {\n if (program?.format !== \"CJS_SHADER_IR\" || program.formatVersion !== 1)\n {\n throw new TypeError(`BuildWgslBindingPlan program ${index} is not CJS_SHADER_IR version 1`);\n }\n const stage = STAGE_VISIBILITY[program.stage];\n if (!stage)\n {\n throw new Error(`BuildWgslBindingPlan program ${index} has unsupported stage ${program.stage || \"unknown\"}`);\n }\n if (programStages.has(stage))\n {\n throw new Error(`BuildWgslBindingPlan contains multiple ${stage} programs for one pass`);\n }\n programStages.add(stage);\n const layoutPolicy = particleClearSignedAtomicLayoutPolicy(\n program,\n options.effectProfileProof ?? null\n ) ?? particleEmitSignedAtomicLayoutPolicy(program);\n for (const binding of lowerBindingLayout(\n program,\n null,\n layoutPolicy,\n resourceTransformPlan\n ))\n {\n const key = identity(binding);\n const entry = portableBinding(binding);\n if (!identities.has(key)) identities.set(key, []);\n identities.get(key).push({ binding: entry, stage });\n }\n }\n if (programStages.has(\"compute\") && programStages.size !== 1)\n {\n throw new Error(\"BuildWgslBindingPlan cannot mix compute and render programs in one pass\");\n }\n\n const bindings = [];\n for (const [ key, occurrences ] of identities)\n {\n const stages = occurrences.map((entry) => entry.stage)\n .sort((left, right) => STAGE_ORDER[left] - STAGE_ORDER[right]);\n if (sharedIdentities.has(key))\n {\n if (occurrences.length < 2)\n {\n throw new Error(`WGSL shared identity ${key} does not occur in multiple stages`);\n }\n const expected = fingerprint(occurrences[0].binding);\n if (occurrences.some((entry) => fingerprint(entry.binding) !== expected))\n {\n throw new Error(`WGSL shared identity ${key} has incompatible stage declarations`);\n }\n bindings.push({ ...occurrences[0].binding, scopeIdentity: key, stages });\n continue;\n }\n for (const occurrence of occurrences)\n {\n bindings.push({\n ...occurrence.binding,\n scopeIdentity: `${key}@${occurrence.stage}`,\n stages: [ occurrence.stage ]\n });\n }\n }\n for (const key of sharedIdentities)\n {\n if (!identities.has(key)) throw new Error(`WGSL shared identity ${key} does not occur in the pass`);\n }\n\n bindings.sort((left, right) =>\n left.registerSpace - right.registerSpace\n || (KIND_ORDER[left.resourceKind] ?? 99) - (KIND_ORDER[right.resourceKind] ?? 99)\n || left.registerIndex - right.registerIndex\n || (STAGE_ORDER[left.stages[0]] ?? 99) - (STAGE_ORDER[right.stages[0]] ?? 99)\n || left.generatedSymbol.localeCompare(right.generatedSymbol)\n || left.scopeIdentity.localeCompare(right.scopeIdentity));\n const plannedBindings = bindings\n .map((binding, bindingIndex) => ({ ...binding, group: 0, binding: bindingIndex }));\n\n // WebGPU pipeline creation requires the vertex output and fragment input\n // interpolation attributes at one location to MATCH, and interpolation is\n // declared only on the fragment side in DXBC (dcl_input_ps). Record the\n // non-default modes here so the vertex module can mirror them.\n const varyingInterpolation = {};\n for (const program of programs)\n {\n if (program.stage !== \"pixel\") continue;\n for (const declaration of program.declarations || [])\n {\n if (declaration.opcodeName !== \"dcl_input_ps\") continue;\n if (declaration.data?.interpolationModeName === \"linear_noperspective\")\n {\n varyingInterpolation[declaration.data.registerIndex] = \"linear\";\n }\n }\n }\n\n return deepFreeze({\n format: \"CJS_WGSL_BINDING_PLAN\",\n formatVersion: resourceTransformPlan ? 3 : 2,\n ...(sharedIdentities.size ? { sharedIdentities: Object.freeze([ ...sharedIdentities ].sort()) } : {}),\n ...(Object.keys(varyingInterpolation).length ? { varyingInterpolation } : {}),\n ...(resourceTransformPlan\n ? { resourceTransforms: resourceTransformPlan.resourceTransforms }\n : {}),\n bindings: plannedBindings\n });\n}\n"],"names":["KIND_ORDER","Object","freeze","sampler","STAGE_VISIBILITY","vertex","pixel","compute","STAGE_ORDER","fragment","IDENTITY_PATTERN","identity","binding","resourceKind","registerSpace","registerIndex","portableBinding","d3dIdentity","generatedSymbol","type","transformId","arrayLayerCount","Number","isInteger","structureStride","buffer","texture","fingerprint","JSON","stringify","deepFreeze","value","isFrozen","entry","values","buildWgslBindingPlan","programs","options","Array","isArray","length","TypeError","requestedShared","sharedIdentities","undefined","some","test","Set","size","resourceTransformPlan","normalizeResourceTransformPlan","identities","Map","programStages","index","program","entries","format","formatVersion","stage","Error","has","add","layoutPolicy","particleClearSignedAtomicLayoutPolicy","effectProfileProof","particleEmitSignedAtomicLayoutPolicy","lowerBindingLayout","key","set","get","push","bindings","occurrences","stages","map","sort","left","right","expected","scopeIdentity","occurrence","localeCompare","plannedBindings","bindingIndex","group","varyingInterpolation","declaration","declarations","opcodeName","data","interpolationModeName","keys","resourceTransforms"],"mappings":"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"}
|