@carbonenginejs/runtime-resource 0.12.1 → 0.13.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/LICENSE +21 -21
- package/NOTICE +32 -32
- package/README.md +129 -108
- package/dist/CjsMotherLode.js +1271 -1271
- package/dist/CjsResMan.js +3858 -3494
- package/dist/CjsResMan.js.map +1 -1
- package/dist/CjsResManFetchProvider.js +94 -94
- package/dist/CjsResManWorkQueue.js +301 -301
- package/dist/_virtual/_rollupPluginBabelHelpers.js +150 -150
- package/dist/format/CjsBlueReader.js +358 -358
- package/dist/format/CjsByteReader.js +310 -310
- package/dist/format/CjsByteWriter.js +242 -242
- package/dist/format/CjsFormat.js +223 -223
- package/dist/format/CjsFormatError.js +41 -41
- package/dist/format/CjsReader.js +22 -22
- package/dist/format/CjsResourceProbe.js +279 -279
- package/dist/format/CjsStringTable.js +268 -268
- package/dist/format/carbonEffect/CjsCarbonEffectReader.js +408 -361
- package/dist/format/carbonEffect/CjsCarbonEffectReader.js.map +1 -1
- package/dist/format/carbonEffect/CjsCarbonEffectWriter.js +373 -373
- package/dist/format/carbonEffect/buildCarbonEffectContainer.js +182 -0
- package/dist/format/carbonEffect/buildCarbonEffectContainer.js.map +1 -0
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js +321 -427
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectRecords.js +1147 -955
- package/dist/format/carbonEffect/carbonEffectRecords.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectResourceTransform.js +197 -0
- package/dist/format/carbonEffect/carbonEffectResourceTransform.js.map +1 -0
- package/dist/format/compareUtf8.js +36 -36
- package/dist/format/effect/effectBodyInventory.js +146 -0
- package/dist/format/effect/effectBodyInventory.js.map +1 -0
- package/dist/format/effect/effectPermutationGraph.js +257 -257
- package/dist/format/effect/effectPermutationGraph.js.map +1 -1
- package/dist/format/effect/sha256.js +114 -114
- package/dist/format/index.js +11 -11
- package/dist/format/payloadContract.js +193 -193
- package/dist/formats/black/CjsBlackFormat.js +310 -292
- package/dist/formats/black/CjsBlackFormat.js.map +1 -1
- package/dist/formats/black/core/CjsBlackBinaryReader.js +260 -260
- package/dist/formats/black/core/CjsBlackPropertyReaders.js +448 -448
- package/dist/formats/black/core/CjsBlackReader.js +764 -764
- package/dist/formats/black/core/CjsBlackSchemaRegistry.js +540 -540
- package/dist/formats/black/core/black-schema-v1-2026-07-23.json.js +4 -4
- package/dist/formats/black/core/blackConstants.js +7 -7
- package/dist/formats/black/core/blackDefinitions.js +10 -10
- package/dist/formats/black/core/blackEnums.js +6 -6
- package/dist/formats/black/core/blackSchema.js +3 -3
- package/dist/formats/black/core/blackVersion.js +22 -22
- package/dist/formats/black/core/helpers.js +199 -199
- package/dist/formats/black/core/schema.js +4 -4
- package/dist/formats/black/index.js +2 -2
- package/dist/formats/bnk/CjsBnkFormat.js +175 -156
- package/dist/formats/bnk/CjsBnkFormat.js.map +1 -1
- package/dist/formats/bnk/core/busNodes.js +252 -0
- package/dist/formats/bnk/core/busNodes.js.map +1 -0
- package/dist/formats/bnk/core/effectNodes.js +147 -0
- package/dist/formats/bnk/core/effectNodes.js.map +1 -0
- package/dist/formats/bnk/core/eventAction.js +416 -305
- package/dist/formats/bnk/core/eventAction.js.map +1 -1
- package/dist/formats/bnk/core/globalSettings.js +215 -0
- package/dist/formats/bnk/core/globalSettings.js.map +1 -0
- package/dist/formats/bnk/core/graph.js +137 -137
- package/dist/formats/bnk/core/helpers.js +512 -480
- package/dist/formats/bnk/core/helpers.js.map +1 -1
- package/dist/formats/bnk/core/musicNodes.js +533 -509
- package/dist/formats/bnk/core/musicNodes.js.map +1 -1
- package/dist/formats/bnk/core/nodeBase.js +553 -532
- package/dist/formats/bnk/core/nodeBase.js.map +1 -1
- package/dist/formats/bnk/core/sfxNodes.js +632 -632
- package/dist/formats/bnk/core/soundbanksInfo.js +209 -209
- package/dist/formats/bnk/index.js +2 -2
- package/dist/formats/cmf/CjsCmfFormat.js +497 -497
- package/dist/formats/cmf/core/binary.js +194 -194
- package/dist/formats/cmf/core/buffers.js +237 -237
- package/dist/formats/cmf/core/constants.js +47 -47
- package/dist/formats/cmf/core/gr2Anim.js +453 -453
- package/dist/formats/cmf/core/helpers.js +318 -318
- package/dist/formats/cmf/core/pack.js +276 -276
- package/dist/formats/cmf/core/schema.js +374 -374
- package/dist/formats/cmf/core/shared.js +277 -277
- package/dist/formats/cmf/core/writer.js +571 -571
- package/dist/formats/cmf/index.js +2 -2
- package/dist/formats/dds/CjsDdsFormat.js +200 -200
- package/dist/formats/dds/core/bc6h.js +298 -298
- package/dist/formats/dds/core/bc7.js +272 -272
- package/dist/formats/dds/core/helpers.js +862 -862
- package/dist/formats/dds/index.js +2 -2
- package/dist/formats/dxbc/CjsDxbcFormat.js +142 -142
- package/dist/formats/dxbc/core/DxbcReader.js +266 -266
- package/dist/formats/dxbc/core/container.js +169 -169
- package/dist/formats/dxbc/core/decoder.js +789 -789
- package/dist/formats/dxbc/core/errors.js +19 -19
- package/dist/formats/dxbc/core/helpers.js +220 -220
- package/dist/formats/dxbc/core/opcodes.js +45 -45
- package/dist/formats/dxbc/core/program.js +91 -91
- package/dist/formats/dxbc/core/signature.js +172 -172
- package/dist/formats/dxbc/index.js +2 -2
- package/dist/formats/fbx/CjsFbxFormat.js +266 -266
- package/dist/formats/fbx/core/helpers.js +3932 -3932
- package/dist/formats/fbx/index.js +2 -2
- package/dist/formats/flac/CjsFlacFormat.js +142 -142
- package/dist/formats/flac/core/helpers.js +315 -315
- package/dist/formats/flac/index.js +2 -2
- package/dist/formats/gif/CjsGifFormat.js +141 -141
- package/dist/formats/gif/core/helpers.js +380 -380
- package/dist/formats/gif/index.js +2 -2
- package/dist/formats/gltf/CjsGltfFormat.js +290 -290
- package/dist/formats/gltf/core/helpers.js +307 -307
- package/dist/formats/gltf/core/json.js +79 -79
- package/dist/formats/gltf/core/parser.js +679 -679
- package/dist/formats/gltf/core/targets.js +173 -173
- package/dist/formats/gltf/index.js +2 -2
- package/dist/formats/gr2/CjsGr2Format.js +289 -289
- package/dist/formats/gr2/core/bitknit2.js +282 -282
- package/dist/formats/gr2/core/curves.js +1047 -1047
- package/dist/formats/gr2/core/gsf.js +72 -72
- package/dist/formats/gr2/core/helpers.js +352 -352
- package/dist/formats/gr2/core/json.js +622 -622
- package/dist/formats/gr2/core/oodle1.js +388 -388
- package/dist/formats/gr2/core/tangents.js +48 -48
- package/dist/formats/gr2/core/targets.js +361 -361
- package/dist/formats/gr2/index.js +2 -2
- package/dist/formats/hlsl/CjsHlslFormat.js +254 -254
- package/dist/formats/hlsl/core/HlslBinaryUtils.js +15 -15
- package/dist/formats/hlsl/core/HlslEffectReadError.js +19 -19
- package/dist/formats/hlsl/core/HlslEffectStateManager.js +130 -130
- package/dist/formats/hlsl/core/HlslRenderStateSetup.js +37 -37
- package/dist/formats/hlsl/core/HlslResourceSetDescription.js +94 -94
- package/dist/formats/hlsl/core/HlslShaderBytecode.js +44 -44
- package/dist/formats/hlsl/core/analysis.js +51 -51
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js +850 -781
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js.map +1 -1
- package/dist/formats/hlsl/core/detailMapFamily.js +128 -0
- package/dist/formats/hlsl/core/detailMapFamily.js.map +1 -0
- package/dist/formats/hlsl/core/helpers.js +270 -270
- package/dist/formats/hlsl/core/json.js +284 -284
- package/dist/formats/hlsl/core/localLightFamily.js +133 -0
- package/dist/formats/hlsl/core/localLightFamily.js.map +1 -0
- package/dist/formats/hlsl/core/metadata.js +327 -327
- package/dist/formats/hlsl/core/render-states.js +280 -280
- package/dist/formats/hlsl/core/tr2/HlslRenderContextEnum.js +43 -43
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js +320 -314
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js.map +1 -1
- package/dist/formats/hlsl/core/tr2/resources/HlslShaderPermutation.js +33 -33
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +416 -416
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectConstant.js +40 -40
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js +62 -742
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js.map +1 -1
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectLibrary.js +52 -52
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectParameterAnnotation.js +38 -38
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectResource.js +50 -50
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectStageInput.js +86 -86
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectTechnique.js +31 -31
- package/dist/formats/hlsl/core/tr2/shader/HlslPass.js +42 -42
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerDescription.js +55 -55
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerSetup.js +29 -29
- package/dist/formats/hlsl/core/tr2/shader/HlslShader.js +220 -220
- package/dist/formats/hlsl/core/tr2/shader/HlslShaderOption.js +30 -30
- package/dist/formats/hlsl/index.js +3 -3
- package/dist/formats/index.js +33 -31
- package/dist/formats/index.js.map +1 -1
- package/dist/formats/jpeg/CjsJpegFormat.js +212 -212
- package/dist/formats/jpeg/core/helpers.js +402 -402
- package/dist/formats/jpeg/core/jpeg.js +480 -480
- package/dist/formats/jpeg/index.js +2 -2
- package/dist/formats/mp3/CjsMp3Format.js +197 -197
- package/dist/formats/mp3/core/helpers.js +375 -375
- package/dist/formats/mp3/index.js +2 -2
- package/dist/formats/mp4/CjsMp4Format.js +197 -197
- package/dist/formats/mp4/core/helpers.js +484 -484
- package/dist/formats/mp4/index.js +2 -2
- package/dist/formats/obj/CjsObjFormat.js +253 -253
- package/dist/formats/obj/core/helpers.js +573 -573
- package/dist/formats/obj/core/json.js +64 -64
- package/dist/formats/obj/core/parser.js +321 -321
- package/dist/formats/obj/index.js +2 -2
- package/dist/formats/ogg/CjsOggFormat.js +143 -143
- package/dist/formats/ogg/core/helpers.js +410 -410
- package/dist/formats/ogg/core/imdct.js +178 -178
- package/dist/formats/ogg/core/vorbis.js +1017 -1017
- package/dist/formats/ogg/index.js +2 -2
- package/dist/formats/pickle/CjsPickleFormat.js +214 -0
- package/dist/formats/pickle/CjsPickleFormat.js.map +1 -0
- package/dist/formats/pickle/core/CjsPickleProtocol0Reader.js +551 -0
- package/dist/formats/pickle/core/CjsPickleProtocol0Reader.js.map +1 -0
- package/dist/formats/pickle/index.js +2 -0
- package/dist/formats/pickle/index.js.map +1 -0
- package/dist/formats/png/CjsPngFormat.js +201 -201
- package/dist/formats/png/core/helpers.js +635 -635
- package/dist/formats/png/index.js +2 -2
- package/dist/formats/red/CjsRedFormat.js +263 -263
- package/dist/formats/red/core/CjsRedReader.js +246 -246
- package/dist/formats/red/core/blackDefinitions.js +3 -3
- package/dist/formats/red/core/helpers.js +158 -158
- package/dist/formats/red/core/redGraph.js +71 -68
- package/dist/formats/red/core/redGraph.js.map +1 -1
- package/dist/formats/red/core/schema.js +4 -4
- package/dist/formats/red/index.js +2 -2
- package/dist/formats/stl/CjsStlFormat.js +365 -365
- package/dist/formats/stl/core/helpers.js +261 -261
- package/dist/formats/stl/core/json.js +51 -51
- package/dist/formats/stl/core/stl.js +642 -642
- package/dist/formats/stl/core/targets.js +173 -173
- package/dist/formats/stl/index.js +2 -2
- package/dist/formats/tga/CjsTgaFormat.js +197 -197
- package/dist/formats/tga/core/helpers.js +493 -493
- package/dist/formats/tga/index.js +2 -2
- package/dist/formats/wav/CjsWavFormat.js +198 -198
- package/dist/formats/wav/core/helpers.js +365 -365
- package/dist/formats/wav/index.js +2 -2
- package/dist/formats/webgl/CjsWebglFormat.js +199 -221
- package/dist/formats/webgl/CjsWebglFormat.js.map +1 -1
- package/dist/formats/webgl/core/buildGlslEffectContainer.js +70 -0
- package/dist/formats/webgl/core/buildGlslEffectContainer.js.map +1 -0
- package/dist/formats/webgl/core/effectPackage.js +900 -792
- package/dist/formats/webgl/core/effectPackage.js.map +1 -1
- package/dist/formats/webgl/core/errors.js +27 -27
- package/dist/formats/webgl/core/errors.js.map +1 -1
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +2820 -2678
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
- package/dist/formats/webgl/core/glsl/DxbcGlslHelpers.js +89 -89
- package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js +486 -428
- package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js.map +1 -1
- package/dist/formats/webgl/core/glsl/packedLightFixups.js +98 -0
- package/dist/formats/webgl/core/glsl/packedLightFixups.js.map +1 -0
- package/dist/formats/webgl/core/glslBackendBlock.js +552 -0
- package/dist/formats/webgl/core/glslBackendBlock.js.map +1 -0
- package/dist/formats/webgl/core/glslBackendBodySet.js +243 -0
- package/dist/formats/webgl/core/glslBackendBodySet.js.map +1 -0
- package/dist/formats/webgl/core/{cewgCompleteness.js → glslEffectCompleteness.js} +85 -81
- package/dist/formats/webgl/core/glslEffectCompleteness.js.map +1 -0
- package/dist/formats/webgl/core/helpers.js +167 -306
- package/dist/formats/webgl/core/helpers.js.map +1 -1
- package/dist/formats/webgl/core/inspectGlslEffectContainer.js +122 -0
- package/dist/formats/webgl/core/inspectGlslEffectContainer.js.map +1 -0
- package/dist/formats/webgl/core/readGlslEffectContainer.js +303 -0
- package/dist/formats/webgl/core/readGlslEffectContainer.js.map +1 -0
- package/dist/formats/webgl/index.js +2 -2
- package/dist/formats/webgpu/CjsWebgpuFormat.js +357 -357
- package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js +89 -197
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js.map +1 -1
- package/dist/formats/webgpu/core/{cewgpu/CewgpuContainer.js → carbonWebgpu/CarbonWebgpuContainer.js} +354 -368
- package/dist/formats/webgpu/core/carbonWebgpu/CarbonWebgpuContainer.js.map +1 -0
- package/dist/formats/webgpu/core/{cewgpu → carbonWebgpu}/containerViews.js +355 -355
- package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js.map +1 -0
- package/dist/formats/webgpu/core/{cewgpu → carbonWebgpu}/validateContainer.js +90 -90
- package/dist/formats/webgpu/core/carbonWebgpu/validateContainer.js.map +1 -0
- package/dist/formats/webgpu/core/effectAnalysis.js +82 -82
- package/dist/formats/webgpu/core/effectBackendBodySet.js +289 -289
- package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
- package/dist/formats/webgpu/core/errors.js +20 -20
- package/dist/formats/webgpu/core/errors.js.map +1 -1
- package/dist/formats/webgpu/core/helpers.js +443 -443
- package/dist/formats/webgpu/core/helpers.js.map +1 -1
- package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js +212 -212
- package/dist/formats/webgpu/core/ir/buildControlFlow.js +220 -220
- package/dist/formats/webgpu/core/ir/indexableTemps.js +137 -137
- package/dist/formats/webgpu/core/ir/inferValueTypes.js +449 -449
- package/dist/formats/webgpu/core/ir/lowerDxbcToIr.js +494 -494
- package/dist/formats/webgpu/core/ir/resolveRegisterFlow.js +177 -177
- package/dist/formats/webgpu/core/ir/sourceLanes.js +61 -61
- package/dist/formats/webgpu/core/packageEffect.js +381 -385
- package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
- package/dist/formats/webgpu/core/packageEffectSelection.js +164 -164
- package/dist/formats/webgpu/core/packageEffectSelection.js.map +1 -1
- package/dist/formats/webgpu/core/packageMetadata.js +17 -17
- package/dist/formats/webgpu/core/schema.js +4 -4
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +263 -263
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js +172 -172
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js +320 -320
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/emitWgsl.js +356 -356
- package/dist/formats/webgpu/core/wgsl/hoistEscapingValues.js +77 -77
- package/dist/formats/webgpu/core/wgsl/lowerBindingLayout.js +451 -451
- package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js +735 -735
- package/dist/formats/webgpu/core/wgsl/lowerCreateHistogramsComputeProgram.js +457 -457
- package/dist/formats/webgpu/core/wgsl/lowerFragmentProgram.js +1572 -1572
- package/dist/formats/webgpu/core/wgsl/lowerMergeHistogramsComputeProgram.js +659 -659
- package/dist/formats/webgpu/core/wgsl/lowerParticleClearComputePrograms.js +734 -734
- package/dist/formats/webgpu/core/wgsl/lowerParticleEmitComputeProgram.js +583 -583
- package/dist/formats/webgpu/core/wgsl/lowerSkinVerticesComputeProgram.js +621 -621
- package/dist/formats/webgpu/core/wgsl/lowerSortComputeProgram.js +824 -824
- package/dist/formats/webgpu/core/wgsl/lowerSortInnerComputeProgram.js +697 -697
- package/dist/formats/webgpu/core/wgsl/lowerSortStepComputeProgram.js +559 -559
- package/dist/formats/webgpu/core/wgsl/lowerVertexProgram.js +1328 -1328
- package/dist/formats/webgpu/core/wgsl/particleEmitSemanticDigest.js +110 -110
- package/dist/formats/webgpu/core/wgsl/precisionControls.js +55 -55
- package/dist/formats/webgpu/core/wgsl/selectionPlans.js +717 -717
- package/dist/formats/webgpu/core/wgsl/uniformity.js +78 -78
- package/dist/formats/webgpu/core/wgsl/validateExactComputeIr.js +196 -196
- package/dist/formats/webgpu/core/wgsl/validateHandleOperand.js +37 -37
- package/dist/formats/webgpu/index.js +2 -2
- package/dist/formats/webm/CjsWebmFormat.js +197 -197
- package/dist/formats/webm/core/helpers.js +572 -572
- package/dist/formats/webm/index.js +2 -2
- package/dist/formats/webp/CjsWebpFormat.js +140 -140
- package/dist/formats/webp/core/helpers.js +237 -237
- package/dist/formats/webp/index.js +2 -2
- package/dist/formats/wem/CjsWemFormat.js +250 -250
- package/dist/formats/wem/core/bitStream.js +261 -261
- package/dist/formats/wem/core/codebookLibrary.js +164 -164
- package/dist/formats/wem/core/helpers.js +437 -437
- package/dist/formats/wem/core/packedCodebooksAotuv603.js +30 -30
- package/dist/formats/wem/core/ptadpcm.js +77 -77
- package/dist/formats/wem/core/resolve.js +121 -121
- package/dist/formats/wem/core/wemToOgg.js +485 -485
- package/dist/formats/wem/index.js +2 -2
- package/dist/formats/yaml/CjsYamlFormat.js +134 -134
- package/dist/formats/yaml/CjsYamlFormat.js.map +1 -1
- package/dist/formats/yaml/core/CjsYamlReader.js +400 -402
- package/dist/formats/yaml/core/CjsYamlReader.js.map +1 -1
- package/dist/formats/yaml/core/helpers.js +196 -170
- package/dist/formats/yaml/core/helpers.js.map +1 -1
- package/dist/formats/yaml/index.js +2 -2
- package/dist/index.js +64 -62
- package/dist/index.js.map +1 -1
- package/dist/resource/CjsLoadingObject.js +19 -0
- package/dist/resource/CjsLoadingObject.js.map +1 -0
- package/dist/resource/CjsResource.js +801 -797
- package/dist/resource/CjsResource.js.map +1 -1
- package/dist/resource/ResourceHandlerMode.js +14 -0
- package/dist/resource/ResourceHandlerMode.js.map +1 -0
- package/dist/resource/Tr2LightProfileRes.js +32 -32
- package/dist/resource/audio/AudioGeometryResData.js +47 -47
- package/dist/resource/audio/CjsAudioBufferRes.js +86 -86
- package/dist/resource/audio/CjsAudioRes.js +213 -213
- package/dist/resource/audio/index.js +4 -4
- package/dist/resource/geometry/MeshDecalData.js +37 -37
- package/dist/resource/geometry/MeshDecalLodData.js +34 -34
- package/dist/resource/geometry/TriGeometryRes.js +675 -675
- package/dist/resource/geometry/TriGeometryResAreaData.js +59 -59
- package/dist/resource/geometry/TriGeometryResJointData.js +38 -38
- package/dist/resource/geometry/TriGeometryResLodData.js +88 -88
- package/dist/resource/geometry/TriGeometryResMeshData.js +63 -63
- package/dist/resource/geometry/TriGeometryResSkeletonData.js +34 -34
- package/dist/resource/geometry/TriJointBinding.js +38 -38
- package/dist/resource/geometry/TriMorphTargetGeometryConstants.js +46 -46
- package/dist/resource/geometry/TriRtGeometryConstants.js +88 -88
- package/dist/resource/geometry/granny/GStateBindingCallbackData.js +31 -31
- package/dist/resource/geometry/granny/Tr2GrannyIntersectionResult.js +60 -60
- package/dist/resource/geometry/granny/Tr2GrannyStateRes.js +36 -36
- package/dist/resource/geometry/granny/TriGrannyRes.js +35 -35
- package/dist/resource/geometry/granny/enums.js +10 -10
- package/dist/resource/geometry/granny/index.js +6 -6
- package/dist/resource/geometry/index.js +17 -17
- package/dist/resource/index.js +54 -52
- package/dist/resource/index.js.map +1 -1
- package/dist/resource/resourceBoundary.js +64 -64
- package/dist/resource/shader/Tr2EffectRes.js +336 -431
- package/dist/resource/shader/Tr2EffectRes.js.map +1 -1
- package/dist/resource/shader/Tr2MaterialArea.js +31 -31
- package/dist/resource/shader/Tr2MaterialMesh.js +27 -27
- package/dist/resource/shader/Tr2MaterialRes.js +31 -31
- package/dist/resource/shader/Tr2Shader.js +283 -261
- package/dist/resource/shader/Tr2Shader.js.map +1 -1
- package/dist/resource/shader/Tr2ShaderPermutation.js +43 -43
- package/dist/resource/shader/index.js +17 -17
- package/dist/resource/shader/reflection/Tr2EffectConstant.js +143 -135
- package/dist/resource/shader/reflection/Tr2EffectConstant.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectDefine.js +30 -30
- package/dist/resource/shader/reflection/Tr2EffectDescription.js +114 -109
- package/dist/resource/shader/reflection/Tr2EffectDescription.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js +168 -147
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js +125 -105
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectResource.js +120 -86
- package/dist/resource/shader/reflection/Tr2EffectResource.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js +372 -241
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js +78 -68
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2Pass.js +168 -111
- package/dist/resource/shader/reflection/Tr2Pass.js.map +1 -1
- package/dist/resource/shader/reflection/carbonRecordFields.js +159 -0
- package/dist/resource/shader/reflection/carbonRecordFields.js.map +1 -0
- package/dist/resource/shader/reflection/shaderStage.js +22 -0
- package/dist/resource/shader/reflection/shaderStage.js.map +1 -0
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js +135 -77
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js.map +1 -1
- package/dist/resource/texture/CjsTextureArrayRes.js +472 -472
- package/dist/resource/texture/CjsTextureArrayResParameterProxy.js +179 -179
- package/dist/resource/texture/Tr2ImageRes.js +120 -120
- package/dist/resource/texture/Tr2TextureLodManager.js +82 -82
- package/dist/resource/texture/Tr2TextureLodUpdateRequest.js +37 -37
- package/dist/resource/texture/Tr2TexturePackChannel.js +37 -37
- package/dist/resource/texture/Tr2TexturePipeline.js +54 -54
- package/dist/resource/texture/Tr2TexturePipelineParams.js +34 -34
- package/dist/resource/texture/Tr2TexturePipelineStepCompress.js +40 -40
- package/dist/resource/texture/Tr2TexturePipelineStepGenerateMips.js +22 -22
- package/dist/resource/texture/Tr2TexturePipelineStepLimitSize.js +34 -34
- package/dist/resource/texture/Tr2TexturePipelineStepLoad.js +31 -31
- package/dist/resource/texture/Tr2TexturePipelineStepPack.js +43 -43
- package/dist/resource/texture/TriTextureRes.js +359 -359
- package/dist/resource/texture/index.js +15 -15
- package/dist/resource/texture/texturePipelineBehavior.js +308 -308
- package/dist/worker/CjsResManMainThreadLoader.js +89 -87
- package/dist/worker/CjsResManMainThreadLoader.js.map +1 -1
- package/dist/worker/CjsResManWorker.js +218 -217
- package/dist/worker/CjsResManWorker.js.map +1 -1
- package/dist/worker/CjsResManWorkerLoader.js +437 -434
- package/dist/worker/CjsResManWorkerLoader.js.map +1 -1
- package/dist/worker/protocol.js +12 -12
- package/docs/README.md +98 -98
- package/docs/architecture.md +118 -109
- package/docs/concepts/resource-lifecycle.md +226 -225
- package/docs/concepts/shader-resource-model.md +111 -114
- package/docs/concepts/writing-an-engine-adapter.md +115 -115
- package/docs/formats/README.md +138 -136
- package/docs/formats/carbon-effect-container.md +553 -452
- package/docs/formats/dxbc/README.md +68 -68
- package/docs/formats/dxbc/architecture.md +80 -80
- package/docs/formats/dxbc/reference/api.md +77 -77
- package/docs/formats/dxbc/reference/classes/README.md +9 -9
- package/docs/formats/dxbc/reference/decoded-output.md +122 -122
- package/docs/formats/gr2.md +160 -160
- package/docs/formats/hlsl/README.md +54 -54
- package/docs/formats/hlsl/architecture.md +65 -67
- package/docs/formats/hlsl/guides/hydrating-json-output.md +60 -62
- package/docs/formats/hlsl/guides/reading-effects.md +64 -64
- package/docs/formats/hlsl/reference/advanced-analysis.md +61 -66
- package/docs/formats/hlsl/reference/api.md +92 -98
- package/docs/formats/hlsl/reference/classes/README.md +11 -11
- package/docs/formats/hlsl/reference/json-graph.md +97 -100
- package/docs/formats/pickle.md +82 -0
- package/docs/formats/provenance.md +196 -196
- package/docs/formats/stl.md +37 -37
- package/docs/formats/webgl/README.md +115 -57
- package/docs/formats/webgl/architecture.md +69 -70
- package/docs/formats/webgl/carbon-constant-layouts.md +326 -326
- package/docs/formats/webgl/decl-io.md +1234 -1234
- package/docs/formats/webgl/memory-structured.md +890 -871
- package/docs/formats/webgl/reference/classes/README.md +9 -9
- package/docs/formats/webgl/texture-sample.md +964 -964
- package/docs/formats/webgpu/README.md +84 -84
- package/docs/formats/webgpu/architecture.md +95 -96
- package/docs/formats/webgpu/formats/{cewgpu.md → carbon-webgpu.md} +215 -216
- package/docs/formats/webgpu/guides/effect-packaging.md +189 -191
- package/docs/formats/webgpu/reference/api.md +196 -197
- package/docs/formats/webgpu/reference/classes/README.md +9 -9
- package/docs/formats/webgpu/reference/wgsl-compatibility.md +1546 -1543
- package/docs/formats/wwise.md +146 -85
- package/docs/reference/classes/README.md +35 -35
- package/docs/reference/classes/audio.md +30 -30
- package/docs/reference/classes/core.md +216 -206
- package/docs/reference/classes/dropped.md +46 -46
- package/docs/reference/classes/formats.md +944 -952
- package/docs/reference/classes/resources.md +456 -456
- package/docs/reference/classes/texture.md +26 -26
- package/docs/reference/events.md +117 -117
- package/docs/reference/motherlode-cache.md +275 -275
- package/docs/reference/queues.md +194 -110
- package/docs/reference/reload.md +107 -107
- package/docs/reference/texture-arrays.md +113 -113
- package/docs/reference/texture-pipeline.md +53 -53
- package/docs/reference/workers.md +142 -135
- package/docs/roadmap.md +150 -150
- package/format-notices/black/LICENSE +21 -21
- package/format-notices/black/NOTICE +47 -47
- package/format-notices/bnk/LICENSE +21 -21
- package/format-notices/bnk/NOTICE +21 -21
- package/format-notices/cmf/LICENSE +21 -21
- package/format-notices/cmf/NOTICE +36 -36
- package/format-notices/dds/LICENSE +21 -21
- package/format-notices/dds/NOTICE +14 -14
- package/format-notices/dxbc/LICENSE +21 -21
- package/format-notices/dxbc/NOTICE +20 -20
- package/format-notices/fbx/LICENSE +21 -21
- package/format-notices/fbx/NOTICE +14 -14
- package/format-notices/flac/LICENSE +21 -21
- package/format-notices/flac/NOTICE +14 -14
- package/format-notices/gif/LICENSE +21 -21
- package/format-notices/gif/NOTICE +14 -14
- package/format-notices/gltf/LICENSE +21 -21
- package/format-notices/gltf/NOTICE +27 -27
- package/format-notices/gr2/LICENSE +21 -21
- package/format-notices/gr2/NOTICE +60 -60
- package/format-notices/gr2/THIRD-PARTY-NOTICES.md +93 -93
- package/format-notices/hlsl/LICENSE +21 -21
- package/format-notices/hlsl/NOTICE +25 -25
- package/format-notices/jpeg/LICENSE +21 -21
- package/format-notices/jpeg/NOTICE +14 -14
- package/format-notices/mp3/LICENSE +21 -21
- package/format-notices/mp3/NOTICE +14 -14
- package/format-notices/mp4/LICENSE +21 -21
- package/format-notices/mp4/NOTICE +14 -14
- package/format-notices/obj/LICENSE +21 -21
- package/format-notices/obj/NOTICE +26 -26
- package/format-notices/ogg/LICENSE +21 -21
- package/format-notices/ogg/NOTICE +28 -28
- package/format-notices/png/LICENSE +21 -21
- package/format-notices/png/NOTICE +14 -14
- package/format-notices/red/LICENSE +21 -21
- package/format-notices/red/NOTICE +31 -31
- package/format-notices/stl/LICENSE +21 -21
- package/format-notices/stl/NOTICE +21 -21
- package/format-notices/tga/LICENSE +21 -21
- package/format-notices/tga/NOTICE +14 -14
- package/format-notices/wav/LICENSE +21 -21
- package/format-notices/wav/NOTICE +14 -14
- package/format-notices/webgl/LICENSE +21 -21
- package/format-notices/webgl/NOTICE +35 -35
- package/format-notices/webgpu/LICENSE +21 -21
- package/format-notices/webgpu/NOTICE +31 -31
- package/format-notices/webm/LICENSE +21 -21
- package/format-notices/webm/NOTICE +14 -14
- package/format-notices/webp/LICENSE +21 -21
- package/format-notices/webp/NOTICE +14 -14
- package/format-notices/wem/LICENSE +57 -57
- package/format-notices/wem/NOTICE +33 -33
- package/format-notices/yaml/LICENSE +21 -21
- package/format-notices/yaml/NOTICE +44 -44
- package/package.json +63 -63
- package/dist/format/carbonEffect/carbonDescriptionFromPortable.js +0 -372
- package/dist/format/carbonEffect/carbonDescriptionFromPortable.js.map +0 -1
- package/dist/format/effect/effectReflectionPackage.js +0 -636
- package/dist/format/effect/effectReflectionPackage.js.map +0 -1
- package/dist/formats/hlsl/core/HlslReader.js +0 -16
- package/dist/formats/hlsl/core/HlslReader.js.map +0 -1
- package/dist/formats/hlsl/core/portableReflection.js +0 -848
- package/dist/formats/hlsl/core/portableReflection.js.map +0 -1
- package/dist/formats/hlsl/portable.js +0 -2
- package/dist/formats/hlsl/portable.js.map +0 -1
- package/dist/formats/webgl/core/cewg/CewgPackage.js +0 -340
- package/dist/formats/webgl/core/cewg/CewgPackage.js.map +0 -1
- package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js +0 -104
- package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js.map +0 -1
- package/dist/formats/webgl/core/cewg/binary.js +0 -19
- package/dist/formats/webgl/core/cewg/binary.js.map +0 -1
- package/dist/formats/webgl/core/cewgCompleteness.js.map +0 -1
- package/dist/formats/webgl/core/effectPackageValidation.js +0 -331
- package/dist/formats/webgl/core/effectPackageValidation.js.map +0 -1
- package/dist/formats/webgpu/core/cewgpu/CewgpuContainer.js.map +0 -1
- package/dist/formats/webgpu/core/cewgpu/containerViews.js.map +0 -1
- package/dist/formats/webgpu/core/cewgpu/validateContainer.js.map +0 -1
- package/dist/resource/shader/portable.js +0 -33
- package/dist/resource/shader/portable.js.map +0 -1
- package/docs/formats/hlsl/reference/portable-reflection.md +0 -141
- package/docs/formats/webgl/effect-reflection.md +0 -127
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
const CEWG_MAGIC = "CEWG";
|
|
2
|
-
const CEWG_VERSION = 1;
|
|
3
|
-
const textEncoder = new TextEncoder();
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Builds CarbonEngineJS CEWG shader package bytes.
|
|
7
|
-
*/
|
|
8
|
-
class CewgPackageBuilder {
|
|
9
|
-
/**
|
|
10
|
-
* Builds a CEWG v1 package from ordered chunks.
|
|
11
|
-
*
|
|
12
|
-
* @param {Array<[string, string|object|Uint8Array|ArrayBuffer|ArrayBufferView]>} chunks Ordered package chunks.
|
|
13
|
-
* @returns {Uint8Array} Package bytes.
|
|
14
|
-
*/
|
|
15
|
-
static build(chunks) {
|
|
16
|
-
const encodedChunks = chunks.map(([tag, value]) => ({
|
|
17
|
-
tag: normalizeTag(tag),
|
|
18
|
-
bytes: normalizeChunkValue(value)
|
|
19
|
-
}));
|
|
20
|
-
const tags = new Set();
|
|
21
|
-
for (const chunk of encodedChunks) {
|
|
22
|
-
if (tags.has(chunk.tag)) {
|
|
23
|
-
throw new Error(`CEWG package contains duplicate chunk tag ${chunk.tag}`);
|
|
24
|
-
}
|
|
25
|
-
tags.add(chunk.tag);
|
|
26
|
-
}
|
|
27
|
-
const size = CEWG_MAGIC.length + 8 + encodedChunks.reduce((sum, chunk) => sum + 8 + chunk.bytes.length, 0);
|
|
28
|
-
const out = new Uint8Array(size);
|
|
29
|
-
const view = new DataView(out.buffer, out.byteOffset, out.byteLength);
|
|
30
|
-
let offset = 0;
|
|
31
|
-
offset = writeAscii(out, offset, CEWG_MAGIC);
|
|
32
|
-
view.setUint32(offset, CEWG_VERSION, true);
|
|
33
|
-
offset += 4;
|
|
34
|
-
view.setUint32(offset, encodedChunks.length, true);
|
|
35
|
-
offset += 4;
|
|
36
|
-
for (const chunk of encodedChunks) {
|
|
37
|
-
offset = writeAscii(out, offset, chunk.tag);
|
|
38
|
-
view.setUint32(offset, chunk.bytes.length, true);
|
|
39
|
-
offset += 4;
|
|
40
|
-
out.set(chunk.bytes, offset);
|
|
41
|
-
offset += chunk.bytes.length;
|
|
42
|
-
}
|
|
43
|
-
return out;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Normalizes a package chunk tag.
|
|
49
|
-
*
|
|
50
|
-
* @param {string} tag Four-character chunk tag.
|
|
51
|
-
* @returns {string} Normalized tag.
|
|
52
|
-
*/
|
|
53
|
-
function normalizeTag(tag) {
|
|
54
|
-
if (typeof tag !== "string" || tag.length !== 4 || [...tag].some(character => {
|
|
55
|
-
const code = character.charCodeAt(0);
|
|
56
|
-
return code < 0x21 || code > 0x7e;
|
|
57
|
-
})) {
|
|
58
|
-
throw new Error(`CEWG chunk tag must contain four printable ASCII characters: ${tag}`);
|
|
59
|
-
}
|
|
60
|
-
return tag;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Normalizes a package chunk payload.
|
|
65
|
-
*
|
|
66
|
-
* @param {string|object|Uint8Array|ArrayBuffer|ArrayBufferView} value Chunk payload.
|
|
67
|
-
* @returns {Uint8Array} Payload bytes.
|
|
68
|
-
*/
|
|
69
|
-
function normalizeChunkValue(value) {
|
|
70
|
-
if (typeof value === "string") {
|
|
71
|
-
return textEncoder.encode(value);
|
|
72
|
-
}
|
|
73
|
-
if (value instanceof Uint8Array) {
|
|
74
|
-
return value;
|
|
75
|
-
}
|
|
76
|
-
if (value instanceof ArrayBuffer) {
|
|
77
|
-
return new Uint8Array(value);
|
|
78
|
-
}
|
|
79
|
-
if (ArrayBuffer.isView(value)) {
|
|
80
|
-
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
81
|
-
}
|
|
82
|
-
if (value && typeof value === "object") {
|
|
83
|
-
return textEncoder.encode(`${JSON.stringify(value)}\n`);
|
|
84
|
-
}
|
|
85
|
-
throw new Error("Unsupported CEWG chunk value");
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Writes ASCII text into a byte buffer.
|
|
90
|
-
*
|
|
91
|
-
* @param {Uint8Array} out Output buffer.
|
|
92
|
-
* @param {number} offset Current byte offset.
|
|
93
|
-
* @param {string} value ASCII text.
|
|
94
|
-
* @returns {number} Updated byte offset.
|
|
95
|
-
*/
|
|
96
|
-
function writeAscii(out, offset, value) {
|
|
97
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
98
|
-
out[offset + i] = value.charCodeAt(i) & 0xff;
|
|
99
|
-
}
|
|
100
|
-
return offset + value.length;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export { CewgPackageBuilder };
|
|
104
|
-
//# sourceMappingURL=CewgPackageBuilder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CewgPackageBuilder.js","sources":["../../../../../../src/formats/webgl/core/cewg/CewgPackageBuilder.js"],"sourcesContent":["const CEWG_MAGIC = \"CEWG\";\nconst CEWG_VERSION = 1;\nconst textEncoder = new TextEncoder();\n\n/**\n * Builds CarbonEngineJS CEWG shader package bytes.\n */\nexport class CewgPackageBuilder\n{\n /**\n * Builds a CEWG v1 package from ordered chunks.\n *\n * @param {Array<[string, string|object|Uint8Array|ArrayBuffer|ArrayBufferView]>} chunks Ordered package chunks.\n * @returns {Uint8Array} Package bytes.\n */\n static build(chunks)\n {\n const encodedChunks = chunks.map(([ tag, value ]) => ({\n tag: normalizeTag(tag),\n bytes: normalizeChunkValue(value)\n }));\n const tags = new Set();\n for (const chunk of encodedChunks)\n {\n if (tags.has(chunk.tag))\n {\n throw new Error(`CEWG package contains duplicate chunk tag ${chunk.tag}`);\n }\n tags.add(chunk.tag);\n }\n\n const size = CEWG_MAGIC.length + 8 + encodedChunks.reduce((sum, chunk) => sum + 8 + chunk.bytes.length, 0);\n const out = new Uint8Array(size);\n const view = new DataView(out.buffer, out.byteOffset, out.byteLength);\n let offset = 0;\n\n offset = writeAscii(out, offset, CEWG_MAGIC);\n view.setUint32(offset, CEWG_VERSION, true);\n offset += 4;\n view.setUint32(offset, encodedChunks.length, true);\n offset += 4;\n\n for (const chunk of encodedChunks)\n {\n offset = writeAscii(out, offset, chunk.tag);\n view.setUint32(offset, chunk.bytes.length, true);\n offset += 4;\n out.set(chunk.bytes, offset);\n offset += chunk.bytes.length;\n }\n\n return out;\n }\n}\n\n/**\n * Normalizes a package chunk tag.\n *\n * @param {string} tag Four-character chunk tag.\n * @returns {string} Normalized tag.\n */\nfunction normalizeTag(tag)\n{\n if (typeof tag !== \"string\"\n || tag.length !== 4\n || [ ...tag ].some((character) =>\n {\n const code = character.charCodeAt(0);\n return code < 0x21 || code > 0x7e;\n }))\n {\n throw new Error(`CEWG chunk tag must contain four printable ASCII characters: ${tag}`);\n }\n return tag;\n}\n\n/**\n * Normalizes a package chunk payload.\n *\n * @param {string|object|Uint8Array|ArrayBuffer|ArrayBufferView} value Chunk payload.\n * @returns {Uint8Array} Payload bytes.\n */\nfunction normalizeChunkValue(value)\n{\n if (typeof value === \"string\")\n {\n return textEncoder.encode(value);\n }\n if (value instanceof Uint8Array)\n {\n return value;\n }\n if (value instanceof ArrayBuffer)\n {\n return new Uint8Array(value);\n }\n if (ArrayBuffer.isView(value))\n {\n return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n }\n if (value && typeof value === \"object\")\n {\n return textEncoder.encode(`${JSON.stringify(value)}\\n`);\n }\n throw new Error(\"Unsupported CEWG chunk value\");\n}\n\n/**\n * Writes ASCII text into a byte buffer.\n *\n * @param {Uint8Array} out Output buffer.\n * @param {number} offset Current byte offset.\n * @param {string} value ASCII text.\n * @returns {number} Updated byte offset.\n */\nfunction writeAscii(out, offset, value)\n{\n for (let i = 0; i < value.length; i += 1)\n {\n out[offset + i] = value.charCodeAt(i) & 0xff;\n }\n return offset + value.length;\n}\n"],"names":["CEWG_MAGIC","CEWG_VERSION","textEncoder","TextEncoder","CewgPackageBuilder","build","chunks","encodedChunks","map","tag","value","normalizeTag","bytes","normalizeChunkValue","tags","Set","chunk","has","Error","add","size","length","reduce","sum","out","Uint8Array","view","DataView","buffer","byteOffset","byteLength","offset","writeAscii","setUint32","set","some","character","code","charCodeAt","encode","ArrayBuffer","isView","JSON","stringify","i"],"mappings":"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"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { CjsByteReader } from '../../../../format/CjsByteReader.js';
|
|
2
|
-
import { WebglReadError } from '../errors.js';
|
|
3
|
-
export { asUint8Array } from '@carbonenginejs/runtime-utils/bytes';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Little-endian binary reader for the CEWG package container.
|
|
7
|
-
*
|
|
8
|
-
* The implementation is `CjsByteReader` in `src/format/`; this subclass only
|
|
9
|
-
* supplies the error class and message this format reports. The CEWG container
|
|
10
|
-
* has no string table, so only the raw-byte and `uint32` reads are exercised —
|
|
11
|
-
* but they are now the shared ones rather than a third copy.
|
|
12
|
-
*/
|
|
13
|
-
class WebglReader extends CjsByteReader {
|
|
14
|
-
static ReadError = WebglReadError;
|
|
15
|
-
static endOfDataMessage = "Unexpected end of CEWG package data";
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export { WebglReader };
|
|
19
|
-
//# sourceMappingURL=binary.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"binary.js","sources":["../../../../../../src/formats/webgl/core/cewg/binary.js"],"sourcesContent":["import { CjsByteReader } from \"../../../../format/CjsByteReader.js\";\nimport { WebglReadError } from \"../errors.js\";\n\nexport { asUint8Array } from \"@carbonenginejs/runtime-utils/bytes\";\n\n/**\n * Little-endian binary reader for the CEWG package container.\n *\n * The implementation is `CjsByteReader` in `src/format/`; this subclass only\n * supplies the error class and message this format reports. The CEWG container\n * has no string table, so only the raw-byte and `uint32` reads are exercised —\n * but they are now the shared ones rather than a third copy.\n */\nexport class WebglReader extends CjsByteReader\n{\n static ReadError = WebglReadError;\n\n static endOfDataMessage = \"Unexpected end of CEWG package data\";\n}\n\nexport default WebglReader;\n"],"names":["WebglReader","CjsByteReader","ReadError","WebglReadError","endOfDataMessage"],"mappings":";;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,WAAW,SAASC,aAAa,CAC9C;EACI,OAAOC,SAAS,GAAGC,cAAc;EAEjC,OAAOC,gBAAgB,GAAG,qCAAqC;AACnE;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cewgCompleteness.js","sources":["../../../../../src/formats/webgl/core/cewgCompleteness.js"],"sourcesContent":["/**\n * Inspects CEWG stage records for complete WebGL2 raster passes.\n *\n * Geometry and compute stages are not raster-pair members. A raster pass is\n * complete only when both its vertex and pixel records exist and their shared\n * shader records contain successful translated source.\n *\n * @param {object[]} stages CEWG stage records.\n * @param {object[]} shaders CEWG translated shader records.\n * @returns {{ expectedPassCount: number, completePassCount: number, incompletePasses: object[] }}\n */\nexport function inspectCewgRasterCompleteness(stages, shaders)\n{\n const shaderMap = new Map((shaders || []).map((shader) => [ shader.key, shader ]));\n const usesSharedShaders = Array.isArray(shaders);\n const groups = new Map();\n\n for (const stage of stages || [])\n {\n if (stage.stageName !== \"vertex\" && stage.stageName !== \"pixel\") continue;\n\n const key = [\n stage.bodyKey || \"selected\",\n stage.techniqueName || \"Main\",\n Number.isInteger(stage.passIndex) ? stage.passIndex : 0\n ].join(\":\");\n let group = groups.get(key);\n if (!group)\n {\n group = {\n key,\n bodyKey: stage.bodyKey || \"selected\",\n techniqueName: stage.techniqueName || \"Main\",\n passIndex: Number.isInteger(stage.passIndex) ? stage.passIndex : 0,\n vertex: null,\n pixel: null,\n duplicateStages: []\n };\n groups.set(key, group);\n }\n if (group[stage.stageName])\n {\n group.duplicateStages.push(stage.stageName);\n }\n group[stage.stageName] = stage;\n }\n\n const incompletePasses = [];\n let completePassCount = 0;\n\n for (const group of groups.values())\n {\n const missingStages = [];\n const unavailableStages = [];\n\n for (const stageName of [ \"vertex\", \"pixel\" ])\n {\n const stage = group[stageName];\n if (!stage)\n {\n missingStages.push(stageName);\n continue;\n }\n\n const shader = usesSharedShaders ? shaderMap.get(stage.shaderKey) : stage;\n if (!shader?.hlsl2webgl?.ok || !shader.source)\n {\n unavailableStages.push({\n stageName,\n stageKey: stage.key,\n shaderKey: stage.shaderKey,\n excluded: shader?.excluded || null,\n reason: shader?.hlsl2webgl?.validationError\n || shader?.hlsl2webgl?.reason\n || shader?.hlsl2webgl?.error\n || shader?.excluded?.reason\n || \"translated source is unavailable\"\n });\n }\n }\n\n if (!missingStages.length && !unavailableStages.length && !group.duplicateStages.length)\n {\n completePassCount += 1;\n continue;\n }\n\n incompletePasses.push({\n key: group.key,\n bodyKey: group.bodyKey,\n techniqueName: group.techniqueName,\n passIndex: group.passIndex,\n missingStages,\n unavailableStages,\n duplicateStages: [ ...new Set(group.duplicateStages) ].sort()\n });\n }\n\n return {\n expectedPassCount: groups.size,\n completePassCount,\n incompletePasses\n };\n}\n\n/**\n * Checks the host-side routing contract emitted for compute-as-fragment\n * programs. A boolean marker is insufficient: the runtime needs the original\n * dispatch shape, dispatch-origin uniform, and every UAV render-target route.\n */\nexport function isCewgComputeFragmentContract(value)\n{\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n if (!Array.isArray(value.threadGroup)\n || value.threadGroup.length !== 3\n || value.threadGroup.some((item) => !Number.isSafeInteger(item) || item < 1))\n {\n return false;\n }\n if (value.dispatchOriginUniform !== null\n && (typeof value.dispatchOriginUniform !== \"string\" || !value.dispatchOriginUniform)) return false;\n if (!Array.isArray(value.uavOutputs) || !value.uavOutputs.length) return false;\n\n const locations = new Set();\n const names = new Set();\n const routes = new Set();\n for (const output of value.uavOutputs)\n {\n if (!output || typeof output !== \"object\") return false;\n if (!Number.isSafeInteger(output.register) || output.register < 0) return false;\n if (output.slice !== null && (!Number.isSafeInteger(output.slice) || output.slice < 0)) return false;\n if (!Number.isSafeInteger(output.location) || output.location < 0 || locations.has(output.location)) return false;\n if (typeof output.glslName !== \"string\" || !output.glslName || names.has(output.glslName)) return false;\n const route = `${output.register}:${output.slice === null ? \"dynamic\" : output.slice}`;\n if (routes.has(route)) return false;\n locations.add(output.location);\n names.add(output.glslName);\n routes.add(route);\n }\n return true;\n}\n\nconst DIAGNOSTIC_INTEGRITY_CODES = new Set([\n \"declared_partial_package\",\n \"failed_body\",\n \"failed_metadata_body\",\n \"filtered_package_scope\",\n \"incomplete_pass_stage_family\",\n \"unsupported_pass_stage_family\",\n \"unsupported_stage\",\n \"unavailable_stage_shader\",\n \"unadapted_compute_stage\",\n \"variant_body_has_no_program\"\n]);\n\n/** Returns true only for integrity failures allowed in explicit diagnostic packages. */\nexport function isCewgDiagnosticIntegrityError(error)\n{\n return DIAGNOSTIC_INTEGRITY_CODES.has(error?.code);\n}\n\n/** Requires one unambiguous copy of every runtime-critical CEWG chunk. */\nexport function inspectCewgCoreChunks(chunks)\n{\n const errors = [];\n for (const tag of [ \"INFO\", \"META\", \"GLSL\" ])\n {\n const count = (chunks || []).filter((chunk) => chunk?.tag === tag).length;\n if (count !== 1)\n {\n errors.push({\n code: \"invalid_core_chunk_cardinality\",\n tag,\n count,\n message: `CEWG package must contain exactly one ${tag} chunk; found ${count}`\n });\n }\n }\n return { ok: errors.length === 0, errors };\n}\n\n/** Formats a bounded error message for incomplete CEWG raster passes. */\nexport function formatIncompleteCewgPasses(incompletePasses, limit = 8)\n{\n return (incompletePasses || []).slice(0, limit).map((entry) =>\n {\n const problems = [\n ...entry.missingStages.map((stage) => `missing ${stage}`),\n ...entry.unavailableStages.map((stage) => `${stage.stageName}: ${stage.reason}`),\n ...(entry.duplicateStages || []).map((stage) => `duplicate ${stage}`)\n ];\n return `${entry.bodyKey} ${entry.techniqueName}[${entry.passIndex}] (${problems.join(\", \")})`;\n }).join(\"; \");\n}\n\n/**\n * Inspects the complete all-permutation CEWG graph and declared package\n * failure counts. Legacy selected-only stage arrays receive the stage checks\n * that are possible without variant/body/shader tables.\n */\nexport function inspectCewgPackageIntegrity(info, metadata, glsl)\n{\n const errors = [];\n if (!glsl || typeof glsl !== \"object\")\n {\n addIntegrityError(errors, \"missing_glsl_set\", \"CEWG GLSL stage set is missing\");\n return { ok: false, errors };\n }\n\n checkEnvelopeValue(info, \"format\", \"CEWG\", \"INFO\", errors);\n if (![ 1, 2, 3 ].includes(info?.formatVersion))\n {\n addIntegrityError(\n errors,\n \"invalid_package_envelope\",\n `INFO formatVersion must be 1, 2, or 3, got ${info?.formatVersion ?? \"<missing>\"}`,\n {\n section: \"INFO\",\n field: \"formatVersion\",\n expected: [ 1, 2, 3 ],\n actual: info?.formatVersion ?? null\n }\n );\n }\n checkEnvelopeValue(glsl, \"format\", \"CEWG_GLSL_SET\", \"GLSL\", errors);\n checkEnvelopeValue(glsl, \"formatVersion\", 1, \"GLSL\", errors);\n checkSourceIdentity(info, errors);\n const packageModes = new Map([\n [ \"tr2-effect-webgl-permutations\", \"all\" ],\n [ \"tr2-effect-webgl\", \"selected\" ]\n ]);\n const expectedMode = packageModes.get(info?.packageKind);\n if (!expectedMode)\n {\n addIntegrityError(\n errors,\n \"unsupported_package_kind\",\n `INFO packageKind is not a supported effect package: ${info?.packageKind ?? \"<missing>\"}`\n );\n }\n if (![ \"all\", \"selected\" ].includes(info?.permutationMode))\n {\n addIntegrityError(errors, \"invalid_permutation_mode\", `INFO permutationMode is invalid: ${info?.permutationMode ?? \"<missing>\"}`);\n }\n if (![ \"all\", \"selected\" ].includes(glsl.permutationMode))\n {\n addIntegrityError(errors, \"invalid_permutation_mode\", `GLSL permutationMode is invalid: ${glsl.permutationMode ?? \"<missing>\"}`);\n }\n if (expectedMode && info?.permutationMode !== expectedMode)\n {\n addIntegrityError(\n errors,\n \"package_mode_mismatch\",\n `INFO packageKind ${info.packageKind} requires permutationMode ${expectedMode}`\n );\n }\n if (info?.permutationMode !== glsl.permutationMode)\n {\n addIntegrityError(\n errors,\n \"package_mode_mismatch\",\n `INFO permutationMode ${info?.permutationMode ?? \"<missing>\"} does not match GLSL ${glsl.permutationMode ?? \"<missing>\"}`\n );\n }\n\n checkPackageSelection(info?.selection, glsl.selection, errors);\n if (expectedMode)\n {\n for (const field of [ \"variants\", \"bodies\", \"stages\", \"shaders\" ])\n {\n if (!Array.isArray(glsl[field]))\n {\n addIntegrityError(errors, \"missing_graph_array\", `GLSL ${field} array is required`, { field });\n }\n }\n if (!metadata || typeof metadata !== \"object\")\n {\n addIntegrityError(errors, \"missing_metadata\", \"CEWG META object is required\");\n }\n else\n {\n for (const field of [ \"variants\", \"bodies\", \"permutations\" ])\n {\n if (!Array.isArray(metadata[field]))\n {\n addIntegrityError(errors, \"missing_metadata_array\", `META ${field} array is required`, { field });\n }\n }\n }\n }\n\n const stages = Array.isArray(glsl.stages) ? glsl.stages : [];\n const usesSharedShaders = Array.isArray(glsl.shaders);\n const shaders = usesSharedShaders ? glsl.shaders : [];\n const bodies = Array.isArray(glsl.bodies) ? glsl.bodies : [];\n const variants = Array.isArray(glsl.variants) ? glsl.variants : [];\n const metadataBodies = Array.isArray(metadata?.bodies) ? metadata.bodies : [];\n const metadataVariants = Array.isArray(metadata?.variants) ? metadata.variants : [];\n const stageMap = keyedRecords(stages, \"stage\", errors);\n const shaderMap = usesSharedShaders ? keyedRecords(shaders, \"shader\", errors) : new Map();\n const bodyMap = keyedRecords(bodies, \"body\", errors);\n const metadataBodyMap = keyedRecords(metadataBodies, \"metadata body\", errors);\n const variantMap = usesSharedShaders ? keyedRecords(variants, \"variant\", errors) : new Map();\n const metadataVariantMap = usesSharedShaders\n ? keyedRecords(metadataVariants, \"metadata variant\", errors)\n : new Map();\n if (usesSharedShaders)\n {\n if (!variants.length) addIntegrityError(errors, \"missing_variants\", \"Shared-shader CEWG package has no variants\");\n }\n const referencedStages = new Set();\n const referencedShaders = new Set();\n const referencedBodies = new Set();\n const passGroups = new Map();\n\n for (const field of [ \"failedShaderCount\", \"excludedShaderCount\", \"failedBodyCount\" ])\n {\n const count = Number(info?.[field] || 0);\n if (count > 0)\n {\n addIntegrityError(errors, \"declared_partial_package\", `INFO ${field} is ${count}`, { field, count });\n }\n }\n\n const completeness = inspectCewgRasterCompleteness(stages, usesSharedShaders ? shaders : undefined);\n checkRequiredCount(info, \"bodyStageCount\", stages.length, errors);\n if (usesSharedShaders)\n {\n const excludedShaderCount = shaders.filter((shader) => shader?.excluded).length;\n const failedShaderCount = shaders.filter((shader) => !shader?.hlsl2webgl?.ok && !shader?.excluded).length;\n const failedBodyCount = bodies.filter((body) => body?.error).length;\n const availableShaderCount = shaders.filter((shader) => shader?.hlsl2webgl?.ok && shader.source).length;\n checkRequiredCount(info, \"permutationCount\", variants.length, errors);\n checkRequiredCount(info, \"uniqueBodyCount\", bodies.length, errors);\n checkRequiredCount(info, \"uniqueShaderCount\", shaders.length, errors);\n checkRequiredCount(info, \"translatedShaderCount\", shaders.length - failedShaderCount - excludedShaderCount, errors);\n checkRequiredCount(info, \"excludedShaderCount\", excludedShaderCount, errors);\n checkRequiredCount(info, \"failedShaderCount\", failedShaderCount, errors);\n checkRequiredCount(info, \"failedBodyCount\", failedBodyCount, errors);\n checkRequiredCount(info, \"availableShaderCount\", availableShaderCount, errors);\n checkRequiredCount(info, \"expectedRasterPassCount\", completeness.expectedPassCount, errors);\n checkRequiredCount(info, \"completeRasterPassCount\", completeness.completePassCount, errors);\n checkRequiredCount(info, \"incompleteRasterPassCount\", completeness.incompletePasses.length, errors);\n }\n\n if (usesSharedShaders)\n {\n const permutationIndexes = new Set();\n for (const variant of variants)\n {\n referencedBodies.add(variant.bodyKey);\n if (!bodyMap.has(variant.bodyKey))\n {\n addIntegrityError(\n errors,\n \"missing_variant_body\",\n `Variant ${variant.key || \"<unknown>\"} references missing body ${variant.bodyKey}`,\n { variantKey: variant.key || null, bodyKey: variant.bodyKey || null }\n );\n }\n if (!Number.isSafeInteger(variant.permutationIndex) || variant.permutationIndex < 0)\n {\n addIntegrityError(\n errors,\n \"invalid_permutation_index\",\n `Variant ${variant.key || \"<unknown>\"} has invalid permutation index ${variant.permutationIndex}`,\n { variantKey: variant.key || null, permutationIndex: variant.permutationIndex }\n );\n }\n else if (permutationIndexes.has(variant.permutationIndex))\n {\n addIntegrityError(\n errors,\n \"duplicate_permutation_index\",\n `Permutation index ${variant.permutationIndex} is used more than once`,\n { permutationIndex: variant.permutationIndex }\n );\n }\n else\n {\n permutationIndexes.add(variant.permutationIndex);\n }\n\n const metadataVariant = metadataVariantMap.get(variant.key);\n if (!metadataVariant)\n {\n addIntegrityError(\n errors,\n \"missing_metadata_variant\",\n `GLSL variant ${variant.key || \"<unknown>\"} has no matching metadata variant`,\n { variantKey: variant.key || null }\n );\n }\n else if (metadataVariant.bodyKey !== variant.bodyKey\n || metadataVariant.permutationIndex !== variant.permutationIndex)\n {\n addIntegrityError(\n errors,\n \"variant_metadata_mismatch\",\n `GLSL variant ${variant.key} does not match its metadata body/permutation mapping`,\n { variantKey: variant.key }\n );\n }\n }\n\n for (const variant of metadataVariants)\n {\n if (variant?.key && !variantMap.has(variant.key))\n {\n addIntegrityError(\n errors,\n \"orphan_metadata_variant\",\n `Metadata variant ${variant.key} has no matching GLSL variant`,\n { variantKey: variant.key }\n );\n }\n }\n\n for (const variant of metadataVariants)\n {\n if (!metadataBodyMap.has(variant.bodyKey))\n {\n addIntegrityError(\n errors,\n \"missing_metadata_variant_body\",\n `Metadata variant ${variant.key || \"<unknown>\"} references missing body ${variant.bodyKey}`,\n { variantKey: variant.key || null, bodyKey: variant.bodyKey || null }\n );\n }\n if (variant.tableIndexMatchesPermutationIndex !== true\n || !Number.isSafeInteger(variant.tableIndex)\n || variant.tableIndex < 0\n || variant.tableIndex !== variant.permutationIndex)\n {\n addIntegrityError(\n errors,\n \"permutation_table_mismatch\",\n `Variant ${variant.key || \"<unknown>\"} table index does not match its permutation index`,\n { variantKey: variant.key || null }\n );\n }\n }\n checkPermutationCoverage(metadata?.permutations, info?.permutationMode, variants, errors);\n\n for (const body of bodies)\n {\n if (!metadataBodyMap.has(body.key))\n {\n addIntegrityError(\n errors,\n \"missing_metadata_body\",\n `GLSL body ${body.key || \"<unknown>\"} has no matching metadata body`,\n { bodyKey: body.key || null }\n );\n }\n if (!referencedBodies.has(body.key))\n {\n addIntegrityError(errors, \"orphan_body\", `Body ${body.key} is not referenced by a variant`, { bodyKey: body.key });\n }\n if (body.error)\n {\n addIntegrityError(errors, \"failed_body\", `Body ${body.key} failed: ${body.error}`, { bodyKey: body.key });\n }\n if (!Array.isArray(body.stages))\n {\n addIntegrityError(errors, \"missing_body_stages\", `Body ${body.key} has no stage list`, { bodyKey: body.key });\n continue;\n }\n\n const localStages = new Set();\n for (const stageKey of body.stages)\n {\n if (localStages.has(stageKey))\n {\n addIntegrityError(\n errors,\n \"duplicate_body_stage_reference\",\n `Body ${body.key} references stage ${stageKey} more than once`,\n { bodyKey: body.key, stageKey }\n );\n }\n localStages.add(stageKey);\n referencedStages.add(stageKey);\n\n const stage = stageMap.get(stageKey);\n if (!stage)\n {\n addIntegrityError(\n errors,\n \"missing_body_stage\",\n `Body ${body.key} references missing stage ${stageKey}`,\n { bodyKey: body.key, stageKey }\n );\n }\n else if (stage.bodyKey !== body.key)\n {\n addIntegrityError(\n errors,\n \"stage_body_mismatch\",\n `Stage ${stageKey} belongs to ${stage.bodyKey}, not ${body.key}`,\n { bodyKey: body.key, stageKey, stageBodyKey: stage.bodyKey || null }\n );\n }\n }\n }\n }\n\n for (const body of metadataBodies)\n {\n if (body?.key && !bodyMap.has(body.key))\n {\n addIntegrityError(\n errors,\n \"orphan_metadata_body\",\n `Metadata body ${body.key} has no matching GLSL body`,\n { bodyKey: body.key }\n );\n }\n if (body.error)\n {\n addIntegrityError(\n errors,\n \"failed_metadata_body\",\n `Metadata body ${body.key} failed: ${body.error}`,\n { bodyKey: body.key }\n );\n }\n }\n\n for (const stage of stages)\n {\n if (!stage || typeof stage !== \"object\")\n {\n addIntegrityError(errors, \"invalid_stage_record\", \"GLSL stage record must be an object\");\n continue;\n }\n const expectedStageTypes = { vertex: 0, pixel: 1, compute: 2, geometry: 3, hull: 4, domain: 5 };\n if (typeof stage.techniqueName !== \"string\" || !stage.techniqueName)\n {\n addIntegrityError(errors, \"invalid_stage_technique\", `Stage ${stage.key || \"<unknown>\"} has no technique name`);\n }\n if (!Number.isSafeInteger(stage.passIndex) || stage.passIndex < 0)\n {\n addIntegrityError(\n errors,\n \"invalid_stage_pass_index\",\n `Stage ${stage.key || \"<unknown>\"} has invalid pass index ${stage.passIndex}`,\n { stageKey: stage.key || null, passIndex: stage.passIndex }\n );\n }\n if (expectedStageTypes[stage.stageName] !== stage.stageType)\n {\n addIntegrityError(\n errors,\n \"stage_type_mismatch\",\n `Stage ${stage.key || \"<unknown>\"} type ${stage.stageType} does not match ${stage.stageName || \"<missing>\"}`,\n { stageKey: stage.key || null, stageType: stage.stageType, stageName: stage.stageName || null }\n );\n }\n if (usesSharedShaders)\n {\n const expectedLocalKey = `${stage.techniqueName}.pass${stage.passIndex}.${stage.stageName}`;\n if (stage.localKey !== expectedLocalKey || stage.key !== `${stage.bodyKey}.${expectedLocalKey}`)\n {\n addIntegrityError(\n errors,\n \"stage_key_mismatch\",\n `Stage ${stage.key || \"<unknown>\"} does not match its body/technique/pass/stage identity`,\n { stageKey: stage.key || null }\n );\n }\n }\n if (typeof stage.techniqueName === \"string\"\n && stage.techniqueName\n && Number.isSafeInteger(stage.passIndex)\n && stage.passIndex >= 0)\n {\n const passKey = `${stage.bodyKey || \"selected\"}:${stage.techniqueName}:${stage.passIndex}`;\n const group = passGroups.get(passKey) || [];\n group.push(stage);\n passGroups.set(passKey, group);\n }\n\n if (usesSharedShaders && !bodyMap.has(stage.bodyKey))\n {\n addIntegrityError(\n errors,\n \"missing_stage_body\",\n `Stage ${stage.key} references missing body ${stage.bodyKey}`,\n { stageKey: stage.key, bodyKey: stage.bodyKey || null }\n );\n }\n if (usesSharedShaders && !referencedStages.has(stage.key))\n {\n addIntegrityError(errors, \"orphan_stage\", `Stage ${stage.key} is not referenced by its body`, { stageKey: stage.key });\n }\n\n const shader = usesSharedShaders ? shaderMap.get(stage.shaderKey) : stage;\n if (usesSharedShaders)\n {\n referencedShaders.add(stage.shaderKey);\n if (!shader)\n {\n addIntegrityError(\n errors,\n \"missing_stage_shader\",\n `Stage ${stage.key} references missing shader ${stage.shaderKey}`,\n { stageKey: stage.key, shaderKey: stage.shaderKey || null }\n );\n continue;\n }\n if (shader.stageName !== stage.stageName)\n {\n addIntegrityError(\n errors,\n \"shader_stage_mismatch\",\n `Shader ${shader.key} is ${shader.stageName || \"<missing>\"}, not ${stage.stageName}`,\n { stageKey: stage.key, shaderKey: shader.key }\n );\n }\n for (const field of [ \"bindings\", \"stageInputs\", \"stageOutputs\" ])\n {\n if (!Array.isArray(shader[field]))\n {\n addIntegrityError(\n errors,\n \"missing_runtime_contract\",\n `Shader ${shader.key} has no ${field} runtime contract array`,\n { stageKey: stage.key, shaderKey: shader.key, field }\n );\n }\n }\n\n const metadataBody = metadataBodyMap.get(stage.bodyKey);\n const manifestStages = metadataBody?.manifest?.stages;\n if (!Array.isArray(manifestStages))\n {\n addIntegrityError(\n errors,\n \"missing_manifest_stages\",\n `Metadata body ${stage.bodyKey} has no manifest stage array`,\n { bodyKey: stage.bodyKey, stageKey: stage.key }\n );\n }\n else\n {\n const manifestStage = manifestStages.find((entry) => entry?.techniqueName === stage.techniqueName\n && entry.passIndex === stage.passIndex\n && entry.stageType === stage.stageType\n && entry.stageName === stage.stageName);\n if (!manifestStage)\n {\n addIntegrityError(\n errors,\n \"missing_manifest_stage\",\n `Stage ${stage.key} has no matching META manifest stage`,\n { bodyKey: stage.bodyKey, stageKey: stage.key }\n );\n }\n else if (stage.stageName === \"vertex\" && Array.isArray(shader.stageInputs))\n {\n const expectedInputs = (manifestStage.pipelineInputs || []).filter((input) => Number(input?.usedMask || 0) !== 0);\n for (const input of expectedInputs)\n {\n if (!shader.stageInputs.some((entry) => entry?.register === input.registerIndex\n && normalizeSemanticName(entry.semanticName) === normalizeSemanticName(input.usageName)\n && entry.semanticIndex === input.usageIndex))\n {\n addIntegrityError(\n errors,\n \"vertex_input_contract_mismatch\",\n `Vertex shader ${shader.key} is missing manifest input ${input.usageName}${input.usageIndex} at register ${input.registerIndex}`,\n { stageKey: stage.key, shaderKey: shader.key, register: input.registerIndex }\n );\n }\n }\n }\n if (manifestStage) validateShaderRuntimeContract(shader, stage, manifestStage, errors);\n }\n }\n\n if (![ \"vertex\", \"pixel\", \"compute\" ].includes(stage.stageName))\n {\n addIntegrityError(\n errors,\n \"unsupported_stage\",\n `Stage ${stage.key} uses unsupported WebGL2 stage ${stage.stageName}`,\n { stageKey: stage.key, stageName: stage.stageName || null }\n );\n continue;\n }\n\n if (!shader?.hlsl2webgl?.ok || !shader.source)\n {\n addIntegrityError(\n errors,\n \"unavailable_stage_shader\",\n `Stage ${stage.key} has no successful translated source`,\n { stageKey: stage.key, shaderKey: stage.shaderKey || null }\n );\n }\n if (stage.stageName === \"compute\")\n {\n const computeIssue = computeFragmentShaderIssue(shader);\n if (computeIssue)\n {\n addIntegrityError(\n errors,\n \"unadapted_compute_stage\",\n `Compute stage ${stage.key} ${computeIssue}`,\n { stageKey: stage.key, shaderKey: stage.shaderKey || null }\n );\n }\n }\n }\n\n for (const [ passKey, passStages ] of passGroups)\n {\n const counts = { vertex: 0, pixel: 0, compute: 0, other: 0 };\n for (const stage of passStages)\n {\n if (stage.stageName in counts && stage.stageName !== \"other\") counts[stage.stageName] += 1;\n else counts.other += 1;\n }\n const raster = counts.vertex === 1 && counts.pixel === 1 && counts.compute === 0 && counts.other === 0;\n const compute = counts.vertex === 0 && counts.pixel === 0 && counts.compute === 1 && counts.other === 0;\n if (!raster && !compute)\n {\n const duplicate = Object.values(counts).some((count) => count > 1);\n const mixed = counts.compute > 0 && (counts.vertex > 0 || counts.pixel > 0);\n const code = duplicate || mixed\n ? \"invalid_pass_stage_family\"\n : counts.other > 0\n ? \"unsupported_pass_stage_family\"\n : \"incomplete_pass_stage_family\";\n addIntegrityError(\n errors,\n code,\n `Pass ${passKey} must contain exactly one vertex/pixel pair or one compute stage`,\n { passKey, counts }\n );\n }\n }\n\n if (usesSharedShaders)\n {\n for (const shader of shaders)\n {\n if (!referencedShaders.has(shader.key))\n {\n addIntegrityError(errors, \"orphan_shader\", `Shader ${shader.key} is not referenced by a stage`, { shaderKey: shader.key });\n }\n }\n\n const completeBodies = new Set();\n for (const stage of stages)\n {\n const shader = shaderMap.get(stage.shaderKey);\n if (stage.stageName === \"compute\"\n && isCewgComputeFragmentContract(shader?.computeFragment)\n && shader?.hlsl2webgl?.ok\n && shader.source)\n {\n completeBodies.add(stage.bodyKey);\n }\n }\n for (const body of bodies)\n {\n if (completeness.incompletePasses.some((pass) => pass.bodyKey === body.key)) continue;\n if (completeness.expectedPassCount > 0)\n {\n const hasCompleteRaster = stages.some((stage) =>\n stage.bodyKey === body.key\n && stage.stageName === \"vertex\"\n && completeness.incompletePasses.every((pass) =>\n pass.bodyKey !== body.key\n || pass.techniqueName !== stage.techniqueName\n || pass.passIndex !== stage.passIndex\n )\n && stages.some((pixel) =>\n pixel.bodyKey === body.key\n && pixel.techniqueName === stage.techniqueName\n && pixel.passIndex === stage.passIndex\n && pixel.stageName === \"pixel\"\n )\n );\n if (hasCompleteRaster) completeBodies.add(body.key);\n }\n }\n for (const variant of variants)\n {\n if (bodyMap.has(variant.bodyKey) && !completeBodies.has(variant.bodyKey))\n {\n addIntegrityError(\n errors,\n \"variant_body_has_no_program\",\n `Variant ${variant.key || \"<unknown>\"} body ${variant.bodyKey} has no complete WebGL2 program`,\n { variantKey: variant.key || null, bodyKey: variant.bodyKey || null }\n );\n }\n }\n }\n\n return { ok: errors.length === 0, errors };\n}\n\n/** Formats bounded package-integrity errors for CLI output. */\nexport function formatCewgIntegrityErrors(errors, limit = 8)\n{\n return (errors || []).slice(0, limit).map((entry) => `${entry.code}: ${entry.message}`).join(\"; \");\n}\n\nfunction keyedRecords(records, label, errors)\n{\n const map = new Map();\n for (const record of records)\n {\n if (!record?.key)\n {\n addIntegrityError(errors, `missing_${label.replace(/\\s+/g, \"_\")}_key`, `${label} record has no key`);\n continue;\n }\n if (map.has(record.key))\n {\n addIntegrityError(errors, `duplicate_${label.replace(/\\s+/g, \"_\")}_key`, `Duplicate ${label} key ${record.key}`);\n continue;\n }\n map.set(record.key, record);\n }\n return map;\n}\n\nfunction checkPackageSelection(infoSelection, glslSelection, errors)\n{\n const valid = (selection) => selection\n && typeof selection === \"object\"\n && !Array.isArray(selection)\n && (selection.technique === null || (typeof selection.technique === \"string\" && selection.technique.length > 0))\n && (selection.pass === null || (Number.isSafeInteger(selection.pass) && selection.pass >= 0))\n && (selection.stage === null || (typeof selection.stage === \"string\" && selection.stage.length > 0));\n if (!valid(infoSelection) || !valid(glslSelection))\n {\n addIntegrityError(errors, \"invalid_package_selection\", \"INFO and GLSL must contain valid selection descriptors\");\n return;\n }\n if (infoSelection.technique !== glslSelection.technique\n || infoSelection.pass !== glslSelection.pass\n || infoSelection.stage !== glslSelection.stage)\n {\n addIntegrityError(errors, \"package_selection_mismatch\", \"INFO and GLSL selection descriptors do not match\");\n }\n if (infoSelection.technique !== null || infoSelection.pass !== null || infoSelection.stage !== null)\n {\n addIntegrityError(\n errors,\n \"filtered_package_scope\",\n \"Technique/pass/stage filters produce a diagnostic partial package\",\n { selection: { ...infoSelection } }\n );\n }\n}\n\nfunction checkPermutationCoverage(permutations, mode, variants, errors)\n{\n if (!Array.isArray(permutations)) return;\n let count = 1;\n let defaultIndex = 0;\n let multiplier = 1;\n const names = new Set();\n for (const permutation of permutations)\n {\n const optionCount = Array.isArray(permutation?.options) ? permutation.options.length : 0;\n if (typeof permutation?.name !== \"string\" || !permutation.name || names.has(permutation.name))\n {\n addIntegrityError(\n errors,\n \"invalid_permutation_description\",\n `Permutation name is missing or duplicated: ${permutation?.name || \"<missing>\"}`\n );\n return;\n }\n names.add(permutation.name);\n if (optionCount < 1)\n {\n addIntegrityError(\n errors,\n \"invalid_permutation_description\",\n `Permutation ${permutation?.name || \"<unknown>\"} has no options`\n );\n return;\n }\n const optionValues = new Set();\n if (permutation.options.some((option) => typeof option !== \"string\" || !option || optionValues.has(option)\n || !optionValues.add(option)))\n {\n addIntegrityError(\n errors,\n \"invalid_permutation_description\",\n `Permutation ${permutation.name} has a missing or duplicate option value`\n );\n return;\n }\n if (!Number.isSafeInteger(permutation.defaultOption)\n || permutation.defaultOption < 0\n || permutation.defaultOption >= optionCount)\n {\n addIntegrityError(\n errors,\n \"invalid_permutation_description\",\n `Permutation ${permutation.name || \"<unknown>\"} has invalid default option ${permutation.defaultOption}`\n );\n return;\n }\n defaultIndex += permutation.defaultOption * multiplier;\n multiplier *= optionCount;\n count *= optionCount;\n if (!Number.isSafeInteger(count) || !Number.isSafeInteger(defaultIndex))\n {\n addIntegrityError(errors, \"invalid_permutation_description\", \"Permutation table exceeds safe integer range\");\n return;\n }\n }\n\n const indexes = new Set(variants.map((variant) => variant?.permutationIndex));\n if (mode === \"all\")\n {\n if (variants.length !== count)\n {\n addIntegrityError(\n errors,\n \"incomplete_permutation_coverage\",\n `All-permutation package has ${variants.length} variants, expected ${count}`,\n { actual: variants.length, expected: count }\n );\n return;\n }\n for (let index = 0; index < count; index += 1)\n {\n if (!indexes.has(index))\n {\n addIntegrityError(\n errors,\n \"incomplete_permutation_coverage\",\n `All-permutation package is missing index ${index}`,\n { permutationIndex: index }\n );\n break;\n }\n }\n }\n else if (mode === \"selected\"\n && (variants.length !== 1 || variants[0]?.permutationIndex !== defaultIndex))\n {\n addIntegrityError(\n errors,\n \"invalid_selected_permutation\",\n `Selected package must contain only default permutation index ${defaultIndex}`,\n { expected: defaultIndex, actual: variants.map((variant) => variant?.permutationIndex) }\n );\n }\n}\n\nfunction checkEnvelopeValue(record, field, expected, label, errors)\n{\n if (record?.[field] !== expected)\n {\n addIntegrityError(\n errors,\n \"invalid_package_envelope\",\n `${label} ${field} must be ${expected}, got ${record?.[field] ?? \"<missing>\"}`,\n { section: label, field, expected, actual: record?.[field] ?? null }\n );\n }\n}\n\nfunction checkSourceIdentity(info, errors)\n{\n const identity = info?.sourceIdentity;\n const optionalString = (value) => value === null || (typeof value === \"string\" && value.length > 0);\n const optionalMd5 = (value) => value === null || /^[0-9a-f]{32}$/u.test(value || \"\");\n const valid = identity\n && typeof identity === \"object\"\n && !Array.isArray(identity)\n && typeof identity.filePath === \"string\"\n && identity.filePath.length > 0\n && optionalString(identity.logicalPath)\n && optionalString(identity.game)\n && optionalString(identity.client)\n && optionalString(identity.build)\n && Number.isSafeInteger(identity.byteLength)\n && identity.byteLength >= 0\n && optionalMd5(identity.md5)\n && /^[0-9a-f]{64}$/u.test(identity.sha256 || \"\")\n && info.sourceByteLength === identity.byteLength\n && info.sourceMd5 === identity.md5\n && info.sourceSha256 === identity.sha256;\n if (!valid)\n {\n addIntegrityError(\n errors,\n \"invalid_source_identity\",\n \"INFO source identity is missing, malformed, or inconsistent with its checksum fields\"\n );\n }\n}\n\nfunction checkRequiredCount(info, field, actual, errors)\n{\n if (!Number.isSafeInteger(info?.[field]) || info[field] < 0)\n {\n addIntegrityError(\n errors,\n \"invalid_declared_count\",\n `INFO ${field} must be a non-negative safe integer`,\n { field, declared: info?.[field] ?? null, actual }\n );\n }\n else if (info[field] !== actual)\n {\n addIntegrityError(\n errors,\n \"declared_count_mismatch\",\n `INFO ${field} is ${info[field]}, graph contains ${actual}`,\n { field, declared: info[field], actual }\n );\n }\n}\n\nfunction computeFragmentShaderIssue(shader)\n{\n const contract = shader?.computeFragment;\n if (!isCewgComputeFragmentContract(contract)) return \"has no valid compute-fragment host contract\";\n if (!Array.isArray(shader.bindings)) return \"has no binding metadata for its compute-fragment host contract\";\n\n const bindings = shader.bindings.filter((binding) => binding?.kind === \"uavTexture\");\n if (bindings.length !== contract.uavOutputs.length)\n {\n return \"compute-fragment UAV routes do not match its binding metadata\";\n }\n for (const output of contract.uavOutputs)\n {\n if (!bindings.some((binding) => binding.registerIndex === output.register\n && binding.slice === output.slice\n && binding.location === output.location\n && binding.name === output.glslName))\n {\n return `compute-fragment route ${output.glslName} does not match its binding metadata`;\n }\n const declaration = new RegExp(\n `layout\\\\s*\\\\(\\\\s*location\\\\s*=\\\\s*${output.location}\\\\s*\\\\)\\\\s*out\\\\b[^;]*\\\\b${escapeRegExp(output.glslName)}\\\\s*;`\n );\n if (!declaration.test(shader.source))\n {\n return `compute-fragment route ${output.glslName} is not declared at output location ${output.location}`;\n }\n }\n\n const dispatchBindings = shader.bindings.filter((binding) => binding?.kind === \"dispatchUniform\");\n if (contract.dispatchOriginUniform === null)\n {\n if (dispatchBindings.length) return \"declares unexpected dispatch-origin binding metadata\";\n }\n else\n {\n if (dispatchBindings.length !== 1 || dispatchBindings[0].name !== contract.dispatchOriginUniform)\n {\n return \"dispatch-origin uniform does not match its binding metadata\";\n }\n const declaration = new RegExp(`uniform\\\\s+ivec3\\\\s+${escapeRegExp(contract.dispatchOriginUniform)}\\\\s*;`);\n if (!declaration.test(shader.source)) return \"dispatch-origin uniform is not declared in translated source\";\n }\n return null;\n}\n\nfunction validateShaderRuntimeContract(shader, stage, manifestStage, errors)\n{\n if (stage.stageName === \"vertex\" && Array.isArray(shader.stageInputs))\n {\n const registers = new Set();\n const names = new Set();\n const expectedInputs = (manifestStage.pipelineInputs || []).filter((input) => Number(input?.usedMask || 0) !== 0);\n for (const input of shader.stageInputs)\n {\n if (!Number.isSafeInteger(input?.register)\n || input.register < 0\n || registers.has(input.register)\n || typeof input.name !== \"string\"\n || !input.name\n || names.has(input.name))\n {\n addIntegrityError(\n errors,\n \"invalid_vertex_input_contract\",\n `Vertex shader ${shader.key} has an invalid or duplicate emitted input`,\n { stageKey: stage.key, shaderKey: shader.key }\n );\n continue;\n }\n registers.add(input.register);\n names.add(input.name);\n if (!expectedInputs.some((entry) => entry.registerIndex === input.register\n && normalizeSemanticName(entry.usageName) === normalizeSemanticName(input.semanticName)\n && entry.usageIndex === input.semanticIndex))\n {\n addIntegrityError(\n errors,\n \"vertex_input_contract_mismatch\",\n `Vertex shader ${shader.key} input ${input.name} is not present in its manifest pipeline inputs`,\n { stageKey: stage.key, shaderKey: shader.key, register: input.register }\n );\n }\n const declaration = new RegExp(`\\\\bin\\\\b[^;]*\\\\b${escapeRegExp(input.name)}\\\\s*;`);\n if (!declaration.test(shader.source))\n {\n addIntegrityError(\n errors,\n \"vertex_input_declaration_mismatch\",\n `Vertex shader ${shader.key} input ${input.name} is not declared in translated source`,\n { stageKey: stage.key, shaderKey: shader.key, inputName: input.name }\n );\n }\n }\n }\n\n if (!Array.isArray(shader.bindings)) return;\n const manifestBindings = Array.isArray(manifestStage.bindings) ? manifestStage.bindings : [];\n for (const binding of shader.bindings)\n {\n if (typeof binding?.samplerType !== \"string\" || !binding.samplerType) continue;\n const uniform = new RegExp(\n `uniform\\\\s+(?:(?:lowp|mediump|highp)\\\\s+)?${escapeRegExp(binding.samplerType)}\\\\s+${escapeRegExp(binding.name)}\\\\s*;`\n );\n if (!uniform.test(shader.source))\n {\n addIntegrityError(\n errors,\n \"sampler_binding_declaration_mismatch\",\n `Shader ${shader.key} sampler ${binding.name || \"<missing>\"} is not declared as ${binding.samplerType}`,\n { stageKey: stage.key, shaderKey: shader.key, bindingName: binding.name || null }\n );\n }\n if (!Number.isSafeInteger(binding.registerIndex)\n || binding.registerIndex < 0\n || !manifestBindings.some((entry) => entry?.kind === \"resource\" && entry.registerIndex === binding.registerIndex))\n {\n addIntegrityError(\n errors,\n \"sampler_resource_contract_mismatch\",\n `Shader ${shader.key} sampler ${binding.name || \"<missing>\"} has no matching manifest resource register`,\n { stageKey: stage.key, shaderKey: shader.key, register: binding.registerIndex }\n );\n }\n\n const comparison = binding.samplerType.endsWith(\"Shadow\");\n if ((binding.comparison === true) !== comparison)\n {\n addIntegrityError(\n errors,\n \"comparison_sampler_contract_mismatch\",\n `Shader ${shader.key} sampler ${binding.name || \"<missing>\"} comparison metadata disagrees with ${binding.samplerType}`,\n { stageKey: stage.key, shaderKey: shader.key, bindingName: binding.name || null }\n );\n }\n if (comparison)\n {\n const samplerRegisters = binding.samplerRegisterIndices;\n if (!Array.isArray(samplerRegisters)\n || !samplerRegisters.length\n || new Set(samplerRegisters).size !== samplerRegisters.length\n || samplerRegisters.some((register) => !Number.isSafeInteger(register)\n || register < 0\n || !manifestBindings.some((entry) => entry?.kind === \"sampler\"\n && entry.registerIndex === register\n && entry.carbon?.sampler?.comparison === true)))\n {\n addIntegrityError(\n errors,\n \"comparison_sampler_contract_mismatch\",\n `Shader ${shader.key} comparison sampler ${binding.name || \"<missing>\"} has invalid manifest sampler pairing`,\n { stageKey: stage.key, shaderKey: shader.key, bindingName: binding.name || null }\n );\n }\n }\n }\n}\n\nfunction normalizeSemanticName(value)\n{\n const name = String(value || \"\").toUpperCase();\n if (name === \"BITANGENT\") return \"BINORMAL\";\n if (name === \"BLENDWEIGHTS\") return \"BLENDWEIGHT\";\n return name;\n}\n\nfunction escapeRegExp(value)\n{\n return String(value).replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction addIntegrityError(errors, code, message, details = {})\n{\n errors.push({ code, message, ...details });\n}\n"],"names":["inspectCewgRasterCompleteness","stages","shaders","shaderMap","Map","map","shader","key","usesSharedShaders","Array","isArray","groups","stage","stageName","bodyKey","techniqueName","Number","isInteger","passIndex","join","group","get","vertex","pixel","duplicateStages","set","push","incompletePasses","completePassCount","values","missingStages","unavailableStages","shaderKey","hlsl2webgl","ok","source","stageKey","excluded","reason","validationError","error","length","Set","sort","expectedPassCount","size"],"mappings":"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"}
|
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
import { EFFECT_PERMUTATION_GRAPH_CHUNK, EFFECT_PERMUTATION_GRAPH_FORMAT, EFFECT_PERMUTATION_GRAPH_VERSION, validateEffectPermutationGraph } from '../../../format/effect/effectPermutationGraph.js';
|
|
2
|
-
import { EFFECT_REFLECTION_CHUNK, EFFECT_REFLECTION_BLOB_CHUNK, validateEffectReflectionPointer, effectReflectionForPermutation } from '../../../format/effect/effectReflectionPackage.js';
|
|
3
|
-
import { inspectCewgRasterCompleteness } from './cewgCompleteness.js';
|
|
4
|
-
import { markEffectReflectionValidated } from './cewg/CewgPackage.js';
|
|
5
|
-
import { sha256Bytes } from '../../../format/effect/sha256.js';
|
|
6
|
-
|
|
7
|
-
const EFFECT_INFO_VERSION = 3;
|
|
8
|
-
const EFFECT_PACKAGE_KINDS = new Set(["tr2-effect-webgl", "tr2-effect-webgl-permutations"]);
|
|
9
|
-
const REQUIRED_EFFECT_CHUNKS = Object.freeze(["INFO", "META", "GLSL"]);
|
|
10
|
-
const SEMANTIC_VERSION = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/u;
|
|
11
|
-
const SHA256 = /^[0-9a-f]{64}$/u;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Validates the canonical CEWG effect envelope after the binary container has
|
|
15
|
-
* been decoded. Generic CEWG containers without a recognized package kind
|
|
16
|
-
* remain readable.
|
|
17
|
-
*
|
|
18
|
-
* @param {object} pkg Loaded CEWG package.
|
|
19
|
-
* @returns {boolean} True when the package is generic, legacy, or valid.
|
|
20
|
-
*/
|
|
21
|
-
function validateEffectPackageEnvelope(pkg) {
|
|
22
|
-
if (!pkg.GetChunk("INFO")) return true;
|
|
23
|
-
const info = requireRecord(pkg.GetJson("INFO"), "CEWG INFO");
|
|
24
|
-
if (!EFFECT_PACKAGE_KINDS.has(info.packageKind)) return true;
|
|
25
|
-
for (const tag of REQUIRED_EFFECT_CHUNKS) {
|
|
26
|
-
if (!pkg.GetChunk(tag)) {
|
|
27
|
-
throw new Error(`CEWG effect package requires ${tag}`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
if (info.format !== "CEWG") {
|
|
31
|
-
throw new Error("CEWG INFO format is malformed");
|
|
32
|
-
}
|
|
33
|
-
if (info.formatVersion === 1) {
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
if (info.formatVersion !== EFFECT_INFO_VERSION) {
|
|
37
|
-
throw new Error(`CEWG INFO schema must be version ${EFFECT_INFO_VERSION}`);
|
|
38
|
-
}
|
|
39
|
-
if (info.targetBackend !== "webgl" || info.backendPackage !== "@carbonenginejs/runtime-resource/formats/webgl" || !SEMANTIC_VERSION.test(info.backendPackageVersion) || info.translator !== "dxbc-js-emitter" || !SEMANTIC_VERSION.test(info.translatorVersion)) {
|
|
40
|
-
throw new Error("CEWG INFO producer provenance is malformed");
|
|
41
|
-
}
|
|
42
|
-
const sourceIdentity = validateSourceIdentity(info.sourceIdentity);
|
|
43
|
-
if (info.sourceByteLength !== sourceIdentity.byteLength || info.sourceSha256 !== sourceIdentity.sha256) {
|
|
44
|
-
throw new Error("CEWG INFO source identity fields disagree");
|
|
45
|
-
}
|
|
46
|
-
requireString(info.sourcePath, "CEWG INFO.sourcePath");
|
|
47
|
-
requireUint(info.defaultPermutationIndex, "CEWG INFO.defaultPermutationIndex");
|
|
48
|
-
requireUint(info.sourceEffectVersion, "CEWG INFO.sourceEffectVersion");
|
|
49
|
-
const expectedMode = info.packageKind === "tr2-effect-webgl-permutations" ? "all" : "selected";
|
|
50
|
-
if (info.permutationMode !== expectedMode) {
|
|
51
|
-
throw new Error("CEWG INFO package kind and permutation mode disagree");
|
|
52
|
-
}
|
|
53
|
-
const graphPointer = requireRecord(info.permutationGraph, "CEWG INFO.permutationGraph");
|
|
54
|
-
if (graphPointer.chunk !== EFFECT_PERMUTATION_GRAPH_CHUNK || graphPointer.format !== EFFECT_PERMUTATION_GRAPH_FORMAT || graphPointer.formatVersion !== EFFECT_PERMUTATION_GRAPH_VERSION || !SHA256.test(graphPointer.sha256)) {
|
|
55
|
-
throw new Error("CEWG INFO.permutationGraph is malformed");
|
|
56
|
-
}
|
|
57
|
-
const graphChunk = pkg.GetChunk(EFFECT_PERMUTATION_GRAPH_CHUNK);
|
|
58
|
-
if (!graphChunk) {
|
|
59
|
-
throw new Error(`CEWG INFO.permutationGraph requires ${EFFECT_PERMUTATION_GRAPH_CHUNK}`);
|
|
60
|
-
}
|
|
61
|
-
if (sha256Bytes(graphChunk.bytes) !== graphPointer.sha256) {
|
|
62
|
-
throw new Error("CEWG INFO permutation-graph digest disagrees with PGRF");
|
|
63
|
-
}
|
|
64
|
-
const graph = requireRecord(pkg.GetJson(EFFECT_PERMUTATION_GRAPH_CHUNK), "CEWG PGRF");
|
|
65
|
-
const graphCounts = validateEffectPermutationGraph(graph, {
|
|
66
|
-
sourceByteLength: sourceIdentity.byteLength
|
|
67
|
-
});
|
|
68
|
-
if (requireUint(graphPointer.permutationCount, "CEWG INFO.permutationGraph.permutationCount") !== graphCounts.permutationCount || requireUint(graphPointer.uniqueBodyCount, "CEWG INFO.permutationGraph.uniqueBodyCount") !== graphCounts.uniqueBodyCount || info.sourcePermutationCount !== graphCounts.permutationCount || info.sourceUniqueBodyCount !== graphCounts.uniqueBodyCount) {
|
|
69
|
-
throw new Error("CEWG INFO permutation-graph counts disagree with PGRF");
|
|
70
|
-
}
|
|
71
|
-
if (info.defaultPermutationIndex >= graphCounts.permutationCount) {
|
|
72
|
-
throw new Error("CEWG default permutation index is absent from PGRF");
|
|
73
|
-
}
|
|
74
|
-
const metadata = requireRecord(pkg.GetJson("META"), "CEWG META");
|
|
75
|
-
const glsl = requireRecord(pkg.GetJson("GLSL"), "CEWG GLSL");
|
|
76
|
-
validateBackendGraph(info, metadata, glsl, graph);
|
|
77
|
-
if (metadata.sourcePath !== info.sourcePath) {
|
|
78
|
-
throw new Error("CEWG META source path disagrees with INFO");
|
|
79
|
-
}
|
|
80
|
-
validateCompleteness(info);
|
|
81
|
-
if (info.formatVersion === 2) {
|
|
82
|
-
if (info.sourceEffectVersion < 8 || info.sourceEffectVersion > 14) {
|
|
83
|
-
throw new Error("CEWG INFO v2 source effect version must be 8-14");
|
|
84
|
-
}
|
|
85
|
-
if (Object.prototype.hasOwnProperty.call(info, "effectReflection") || pkg.GetChunk(EFFECT_REFLECTION_CHUNK) || pkg.GetChunk(EFFECT_REFLECTION_BLOB_CHUNK)) {
|
|
86
|
-
throw new Error("CEWG INFO v2 cannot contain complete effect reflection");
|
|
87
|
-
}
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
const reflectionChunk = pkg.GetChunk(EFFECT_REFLECTION_CHUNK);
|
|
91
|
-
const blobChunk = pkg.GetChunk(EFFECT_REFLECTION_BLOB_CHUNK);
|
|
92
|
-
if (!reflectionChunk || !blobChunk) {
|
|
93
|
-
throw new Error("CEWG INFO v3 requires RFLX and RBLB");
|
|
94
|
-
}
|
|
95
|
-
const reflection = requireRecord(pkg.GetJson(EFFECT_REFLECTION_CHUNK), "CEWG RFLX");
|
|
96
|
-
if (info.sourceEffectVersion !== 15 || reflection.source?.effectVersion !== info.sourceEffectVersion) {
|
|
97
|
-
throw new Error("CEWG INFO v3 source effect version disagrees with RFLX");
|
|
98
|
-
}
|
|
99
|
-
validateEffectReflectionPointer(requireRecord(info.effectReflection, "CEWG INFO.effectReflection"), reflection, blobChunk.bytes, {
|
|
100
|
-
permutationGraph: graph,
|
|
101
|
-
sourceIdentity,
|
|
102
|
-
sourcePath: info.sourcePath,
|
|
103
|
-
reflectionBytes: reflectionChunk.bytes
|
|
104
|
-
});
|
|
105
|
-
validateReflectionBackendGraph(reflection, graph, metadata, glsl);
|
|
106
|
-
markEffectReflectionValidated(pkg);
|
|
107
|
-
return true;
|
|
108
|
-
}
|
|
109
|
-
function validateReflectionBackendGraph(reflection, graph, metadata, glsl) {
|
|
110
|
-
const metadataBodies = new Map(metadata.bodies.map(body => [body.key, body]));
|
|
111
|
-
const checkedBodies = new Set();
|
|
112
|
-
for (const variant of metadata.variants) {
|
|
113
|
-
if (checkedBodies.has(variant.bodyKey)) continue;
|
|
114
|
-
checkedBodies.add(variant.bodyKey);
|
|
115
|
-
const metadataBody = metadataBodies.get(variant.bodyKey);
|
|
116
|
-
const reflected = effectReflectionForPermutation(reflection, graph, variant.permutationIndex);
|
|
117
|
-
const manifest = requireRecord(metadataBody?.manifest, `CEWG META body ${variant.bodyKey} manifest`);
|
|
118
|
-
const reflectedPasses = [];
|
|
119
|
-
const reflectedStages = [];
|
|
120
|
-
for (const technique of requireArray(reflected.techniques, `CEWG RFLX body ${variant.bodyKey} techniques`)) {
|
|
121
|
-
for (const [passIndex, pass] of requireArray(technique.passes, `CEWG RFLX technique ${technique.name} passes`).entries()) {
|
|
122
|
-
reflectedPasses.push({
|
|
123
|
-
techniqueName: technique.name,
|
|
124
|
-
passIndex,
|
|
125
|
-
states: pass.renderStates
|
|
126
|
-
});
|
|
127
|
-
for (const stage of requireArray(pass.stages, `CEWG RFLX ${technique.name}.pass${passIndex} stages`)) {
|
|
128
|
-
reflectedStages.push({
|
|
129
|
-
techniqueName: technique.name,
|
|
130
|
-
passIndex,
|
|
131
|
-
stage
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
const manifestPasses = requireArray(manifest.passes, `CEWG META body ${variant.bodyKey} passes`);
|
|
137
|
-
const manifestStages = requireArray(manifest.stages, `CEWG META body ${variant.bodyKey} stages`);
|
|
138
|
-
if (manifestPasses.length !== reflectedPasses.length || manifestStages.length !== reflectedStages.length) {
|
|
139
|
-
throw new Error(`CEWG META body ${variant.bodyKey} disagrees with RFLX pass/stage counts`);
|
|
140
|
-
}
|
|
141
|
-
for (const reflectedPass of reflectedPasses) {
|
|
142
|
-
const manifestPass = manifestPasses.find(entry => entry.techniqueName === reflectedPass.techniqueName && entry.passIndex === reflectedPass.passIndex);
|
|
143
|
-
if (!manifestPass || !jsonEqual(manifestPass.states, reflectedPass.states)) {
|
|
144
|
-
throw new Error(`CEWG META pass ${reflectedPass.techniqueName}.pass${reflectedPass.passIndex} disagrees with RFLX`);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
for (const reflectedStage of reflectedStages) {
|
|
148
|
-
const stage = reflectedStage.stage;
|
|
149
|
-
const sourceProgram = stage.sourceProgram;
|
|
150
|
-
const signature = stage.input?.signature;
|
|
151
|
-
const manifestStage = manifestStages.find(entry => entry.techniqueName === reflectedStage.techniqueName && entry.passIndex === reflectedStage.passIndex && entry.stageType === stage.stageType && entry.stageName === stage.stageName);
|
|
152
|
-
if (!manifestStage || sourceProgram?.kind !== "stage" || sourceProgram.stageType !== manifestStage.stageType || sourceProgram.stageName !== manifestStage.stageName || sourceProgram.shaderSize !== manifestStage.shaderBytecode?.shaderSize || sourceProgram.stringTableOffset !== manifestStage.shaderBytecode?.stringTableOffset || !samePipelineInputs(signature?.pipelineInputs, manifestStage.pipelineInputs) || !jsonEqual(signature?.threadGroupSize, manifestStage.threadGroupSize)) {
|
|
153
|
-
throw new Error(`CEWG META stage ${reflectedStage.techniqueName}.pass${reflectedStage.passIndex}.${stage.stageName} disagrees with RFLX`);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
if (checkedBodies.size !== metadataBodies.size || requireArray(glsl.bodies, "CEWG GLSL.bodies").some(body => !checkedBodies.has(body.key))) {
|
|
158
|
-
throw new Error("CEWG backend body inventory disagrees with RFLX");
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
function validateSourceIdentity(value) {
|
|
162
|
-
const identity = requireRecord(value, "CEWG INFO.sourceIdentity");
|
|
163
|
-
requireString(identity.logicalPath, "CEWG INFO.sourceIdentity.logicalPath");
|
|
164
|
-
requireUint(identity.byteLength, "CEWG INFO.sourceIdentity.byteLength");
|
|
165
|
-
if (!SHA256.test(identity.sha256)) {
|
|
166
|
-
throw new Error("CEWG INFO.sourceIdentity.sha256 is malformed");
|
|
167
|
-
}
|
|
168
|
-
return identity;
|
|
169
|
-
}
|
|
170
|
-
function validateCompleteness(info) {
|
|
171
|
-
const completeness = requireRecord(info.completeness, "CEWG INFO.completeness");
|
|
172
|
-
for (const key of ["packageValid", "sourceComplete", "backendComplete", "runtimeComplete"]) {
|
|
173
|
-
if (typeof completeness[key] !== "boolean") {
|
|
174
|
-
throw new Error(`CEWG INFO.completeness.${key} must be boolean`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if (!completeness.packageValid || completeness.runtimeComplete) {
|
|
178
|
-
throw new Error("CEWG INFO completeness overstates runtime coverage");
|
|
179
|
-
}
|
|
180
|
-
if (info.formatVersion === 3) {
|
|
181
|
-
if (info.sourceBodyCoverage !== "all-unique" || !completeness.sourceComplete || info.backendProgramCoverage !== (selectionCoversWholeEffect(info.selection) ? "all-stages" : "filtered")) {
|
|
182
|
-
throw new Error("CEWG INFO v3 source coverage is inconsistent");
|
|
183
|
-
}
|
|
184
|
-
} else if (Object.prototype.hasOwnProperty.call(info, "sourceBodyCoverage") || Object.prototype.hasOwnProperty.call(info, "backendBodyCoverage") || Object.prototype.hasOwnProperty.call(info, "backendProgramCoverage") || completeness.sourceComplete) {
|
|
185
|
-
throw new Error("CEWG INFO v2 source coverage is inconsistent");
|
|
186
|
-
}
|
|
187
|
-
const expectedBackendCoverage = info.permutationMode === "all" ? "all" : "selected";
|
|
188
|
-
if (info.formatVersion === 3 && info.backendBodyCoverage !== expectedBackendCoverage || completeness.backendComplete) {
|
|
189
|
-
throw new Error("CEWG INFO backend coverage is inconsistent");
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
function selectionCoversWholeEffect(value) {
|
|
193
|
-
const selection = requireRecord(value, "CEWG INFO.selection");
|
|
194
|
-
return selection.technique === null && selection.pass === null && selection.stage === null;
|
|
195
|
-
}
|
|
196
|
-
function validateBackendGraph(info, metadata, glsl, graph) {
|
|
197
|
-
if (glsl.format !== "CEWG_GLSL_SET" || glsl.formatVersion !== 1 || glsl.permutationMode !== info.permutationMode || !jsonEqual(glsl.selection, info.selection)) {
|
|
198
|
-
throw new Error("CEWG GLSL envelope disagrees with INFO");
|
|
199
|
-
}
|
|
200
|
-
const metadataVariants = requireArray(metadata.variants, "CEWG META.variants");
|
|
201
|
-
const glslVariants = requireArray(glsl.variants, "CEWG GLSL.variants");
|
|
202
|
-
const metadataBodies = requireArray(metadata.bodies, "CEWG META.bodies");
|
|
203
|
-
const glslBodies = requireArray(glsl.bodies, "CEWG GLSL.bodies");
|
|
204
|
-
const stages = requireArray(glsl.stages, "CEWG GLSL.stages");
|
|
205
|
-
const shaders = requireArray(glsl.shaders, "CEWG GLSL.shaders");
|
|
206
|
-
if (metadataVariants.length !== info.permutationCount || glslVariants.length !== info.permutationCount) {
|
|
207
|
-
throw new Error("CEWG backend variant counts disagree with INFO");
|
|
208
|
-
}
|
|
209
|
-
const expectedIndices = info.permutationMode === "all" ? graph.variants.map(variant => variant.permutationIndex) : [info.defaultPermutationIndex];
|
|
210
|
-
if (expectedIndices.length !== metadataVariants.length) {
|
|
211
|
-
throw new Error("CEWG backend permutation coverage disagrees with INFO");
|
|
212
|
-
}
|
|
213
|
-
for (let index = 0; index < expectedIndices.length; index++) {
|
|
214
|
-
const expected = expectedIndices[index];
|
|
215
|
-
const metadataVariant = requireRecord(metadataVariants[index], `CEWG META variant ${index}`);
|
|
216
|
-
const glslVariant = requireRecord(glslVariants[index], `CEWG GLSL variant ${index}`);
|
|
217
|
-
if (metadataVariant.permutationIndex !== expected || glslVariant.permutationIndex !== expected || metadataVariant.key !== glslVariant.key || metadataVariant.bodyKey !== glslVariant.bodyKey) {
|
|
218
|
-
throw new Error(`CEWG backend variant ${index} is inconsistent`);
|
|
219
|
-
}
|
|
220
|
-
const sourceVariant = graph.variants[expected];
|
|
221
|
-
if (metadataVariant.bodyOffset !== sourceVariant.sourceRecord.offset || metadataVariant.bodySize !== sourceVariant.sourceRecord.byteLength) {
|
|
222
|
-
throw new Error(`CEWG backend variant ${index} disagrees with PGRF`);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
if (metadataBodies.length !== info.uniqueBodyCount || glslBodies.length !== info.uniqueBodyCount || stages.length !== info.bodyStageCount || shaders.length !== info.uniqueShaderCount) {
|
|
226
|
-
throw new Error("CEWG backend graph counts disagree with INFO");
|
|
227
|
-
}
|
|
228
|
-
const metadataBodyMap = keyedRecordMap(metadataBodies, "CEWG META body");
|
|
229
|
-
const glslBodyMap = keyedRecordMap(glslBodies, "CEWG GLSL body");
|
|
230
|
-
const stageMap = keyedRecordMap(stages, "CEWG GLSL stage");
|
|
231
|
-
const shaderMap = keyedRecordMap(shaders, "CEWG GLSL shader");
|
|
232
|
-
const variantKeys = new Set();
|
|
233
|
-
const referencedBodies = new Set();
|
|
234
|
-
for (const [index, variant] of glslVariants.entries()) {
|
|
235
|
-
if (typeof variant.key !== "string" || !variant.key || variantKeys.has(variant.key) || !glslBodyMap.has(variant.bodyKey) || !metadataBodyMap.has(metadataVariants[index].bodyKey)) {
|
|
236
|
-
throw new Error(`CEWG backend variant ${index} references an invalid body`);
|
|
237
|
-
}
|
|
238
|
-
variantKeys.add(variant.key);
|
|
239
|
-
referencedBodies.add(variant.bodyKey);
|
|
240
|
-
}
|
|
241
|
-
const referencedStages = new Set();
|
|
242
|
-
for (const body of glslBodies) {
|
|
243
|
-
const metadataBody = metadataBodyMap.get(body.key);
|
|
244
|
-
const bodyStages = requireArray(body.stages, `CEWG GLSL body ${body.key}.stages`);
|
|
245
|
-
if (!metadataBody || referencedBodies.has(body.key) === false || bodyStages.length !== new Set(bodyStages).size) {
|
|
246
|
-
throw new Error(`CEWG backend body ${body.key} is inconsistent`);
|
|
247
|
-
}
|
|
248
|
-
for (const stageKey of bodyStages) {
|
|
249
|
-
const stage = stageMap.get(stageKey);
|
|
250
|
-
if (!stage || stage.bodyKey !== body.key) {
|
|
251
|
-
throw new Error(`CEWG backend body ${body.key} references an invalid stage`);
|
|
252
|
-
}
|
|
253
|
-
referencedStages.add(stageKey);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
const referencedShaders = new Set();
|
|
257
|
-
for (const stage of stages) {
|
|
258
|
-
if (!referencedStages.has(stage.key) || !glslBodyMap.has(stage.bodyKey) || !shaderMap.has(stage.shaderKey)) {
|
|
259
|
-
throw new Error(`CEWG backend stage ${stage.key} is inconsistent`);
|
|
260
|
-
}
|
|
261
|
-
referencedShaders.add(stage.shaderKey);
|
|
262
|
-
}
|
|
263
|
-
if (referencedStages.size !== stageMap.size || referencedShaders.size !== shaderMap.size) {
|
|
264
|
-
throw new Error("CEWG backend graph contains orphan stages or shaders");
|
|
265
|
-
}
|
|
266
|
-
const excludedShaderCount = shaders.filter(shader => shader.excluded).length;
|
|
267
|
-
const failedShaderCount = shaders.filter(shader => !shader.hlsl2webgl?.ok && !shader.excluded).length;
|
|
268
|
-
const failedBodyCount = glslBodies.filter(body => body.error).length;
|
|
269
|
-
const availableShaderCount = shaders.filter(shader => shader.hlsl2webgl?.ok && shader.source).length;
|
|
270
|
-
const raster = inspectCewgRasterCompleteness(stages, shaders);
|
|
271
|
-
const counts = {
|
|
272
|
-
translatedShaderCount: shaders.length - failedShaderCount - excludedShaderCount,
|
|
273
|
-
excludedShaderCount,
|
|
274
|
-
failedShaderCount,
|
|
275
|
-
failedBodyCount,
|
|
276
|
-
availableShaderCount,
|
|
277
|
-
expectedRasterPassCount: raster.expectedPassCount,
|
|
278
|
-
completeRasterPassCount: raster.completePassCount,
|
|
279
|
-
incompleteRasterPassCount: raster.incompletePasses.length
|
|
280
|
-
};
|
|
281
|
-
for (const [field, actual] of Object.entries(counts)) {
|
|
282
|
-
if (info[field] !== actual) {
|
|
283
|
-
throw new Error(`CEWG INFO.${field} disagrees with the backend graph`);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
function keyedRecordMap(records, context) {
|
|
288
|
-
const map = new Map();
|
|
289
|
-
for (const [index, value] of records.entries()) {
|
|
290
|
-
const record = requireRecord(value, `${context} ${index}`);
|
|
291
|
-
if (typeof record.key !== "string" || !record.key || map.has(record.key)) {
|
|
292
|
-
throw new Error(`${context} ${index} has a missing or duplicate key`);
|
|
293
|
-
}
|
|
294
|
-
map.set(record.key, record);
|
|
295
|
-
}
|
|
296
|
-
return map;
|
|
297
|
-
}
|
|
298
|
-
function samePipelineInputs(reflected, manifest) {
|
|
299
|
-
const fields = ["usage", "registerIndex", "usageIndex", "usedMask", "type", "dimension"];
|
|
300
|
-
return Array.isArray(reflected) && Array.isArray(manifest) && reflected.length === manifest.length && reflected.every((entry, index) => fields.every(field => entry[field] === manifest[index]?.[field]));
|
|
301
|
-
}
|
|
302
|
-
function requireRecord(value, context) {
|
|
303
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
304
|
-
throw new Error(`${context} must be an object`);
|
|
305
|
-
}
|
|
306
|
-
return value;
|
|
307
|
-
}
|
|
308
|
-
function requireArray(value, context) {
|
|
309
|
-
if (!Array.isArray(value)) {
|
|
310
|
-
throw new Error(`${context} must be an array`);
|
|
311
|
-
}
|
|
312
|
-
return value;
|
|
313
|
-
}
|
|
314
|
-
function requireString(value, context) {
|
|
315
|
-
if (typeof value !== "string" || !value) {
|
|
316
|
-
throw new Error(`${context} must be a non-empty string`);
|
|
317
|
-
}
|
|
318
|
-
return value;
|
|
319
|
-
}
|
|
320
|
-
function requireUint(value, context) {
|
|
321
|
-
if (!Number.isSafeInteger(value) || value < 0) {
|
|
322
|
-
throw new Error(`${context} must be a non-negative safe integer`);
|
|
323
|
-
}
|
|
324
|
-
return value;
|
|
325
|
-
}
|
|
326
|
-
function jsonEqual(left, right) {
|
|
327
|
-
return JSON.stringify(left) === JSON.stringify(right);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
export { EFFECT_INFO_VERSION, validateEffectPackageEnvelope };
|
|
331
|
-
//# sourceMappingURL=effectPackageValidation.js.map
|