@carbonenginejs/runtime-resource 0.12.2 → 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.
Files changed (541) hide show
  1. package/LICENSE +21 -21
  2. package/NOTICE +32 -32
  3. package/README.md +129 -108
  4. package/dist/CjsMotherLode.js +1271 -1271
  5. package/dist/CjsResMan.js +3858 -3494
  6. package/dist/CjsResMan.js.map +1 -1
  7. package/dist/CjsResManFetchProvider.js +94 -94
  8. package/dist/CjsResManWorkQueue.js +301 -301
  9. package/dist/_virtual/_rollupPluginBabelHelpers.js +150 -150
  10. package/dist/format/CjsBlueReader.js +358 -358
  11. package/dist/format/CjsByteReader.js +310 -310
  12. package/dist/format/CjsByteWriter.js +242 -242
  13. package/dist/format/CjsFormat.js +223 -223
  14. package/dist/format/CjsFormatError.js +41 -41
  15. package/dist/format/CjsReader.js +22 -22
  16. package/dist/format/CjsResourceProbe.js +279 -279
  17. package/dist/format/CjsStringTable.js +268 -268
  18. package/dist/format/carbonEffect/CjsCarbonEffectReader.js +408 -361
  19. package/dist/format/carbonEffect/CjsCarbonEffectReader.js.map +1 -1
  20. package/dist/format/carbonEffect/CjsCarbonEffectWriter.js +373 -373
  21. package/dist/format/carbonEffect/buildCarbonEffectContainer.js +182 -0
  22. package/dist/format/carbonEffect/buildCarbonEffectContainer.js.map +1 -0
  23. package/dist/format/carbonEffect/carbonEffectBackendBlock.js +321 -427
  24. package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -1
  25. package/dist/format/carbonEffect/carbonEffectRecords.js +1147 -955
  26. package/dist/format/carbonEffect/carbonEffectRecords.js.map +1 -1
  27. package/dist/format/carbonEffect/carbonEffectResourceTransform.js +197 -0
  28. package/dist/format/carbonEffect/carbonEffectResourceTransform.js.map +1 -0
  29. package/dist/format/compareUtf8.js +36 -36
  30. package/dist/format/effect/effectBodyInventory.js +146 -0
  31. package/dist/format/effect/effectBodyInventory.js.map +1 -0
  32. package/dist/format/effect/effectPermutationGraph.js +257 -257
  33. package/dist/format/effect/effectPermutationGraph.js.map +1 -1
  34. package/dist/format/effect/sha256.js +114 -114
  35. package/dist/format/index.js +11 -11
  36. package/dist/format/payloadContract.js +193 -193
  37. package/dist/formats/black/CjsBlackFormat.js +310 -292
  38. package/dist/formats/black/CjsBlackFormat.js.map +1 -1
  39. package/dist/formats/black/core/CjsBlackBinaryReader.js +260 -260
  40. package/dist/formats/black/core/CjsBlackPropertyReaders.js +448 -448
  41. package/dist/formats/black/core/CjsBlackReader.js +764 -764
  42. package/dist/formats/black/core/CjsBlackSchemaRegistry.js +540 -540
  43. package/dist/formats/black/core/black-schema-v1-2026-07-23.json.js +4 -4
  44. package/dist/formats/black/core/blackConstants.js +7 -7
  45. package/dist/formats/black/core/blackDefinitions.js +10 -10
  46. package/dist/formats/black/core/blackEnums.js +6 -6
  47. package/dist/formats/black/core/blackSchema.js +3 -3
  48. package/dist/formats/black/core/blackVersion.js +22 -22
  49. package/dist/formats/black/core/helpers.js +199 -199
  50. package/dist/formats/black/core/schema.js +4 -4
  51. package/dist/formats/black/index.js +2 -2
  52. package/dist/formats/bnk/CjsBnkFormat.js +175 -156
  53. package/dist/formats/bnk/CjsBnkFormat.js.map +1 -1
  54. package/dist/formats/bnk/core/busNodes.js +252 -0
  55. package/dist/formats/bnk/core/busNodes.js.map +1 -0
  56. package/dist/formats/bnk/core/effectNodes.js +147 -0
  57. package/dist/formats/bnk/core/effectNodes.js.map +1 -0
  58. package/dist/formats/bnk/core/eventAction.js +416 -305
  59. package/dist/formats/bnk/core/eventAction.js.map +1 -1
  60. package/dist/formats/bnk/core/globalSettings.js +215 -0
  61. package/dist/formats/bnk/core/globalSettings.js.map +1 -0
  62. package/dist/formats/bnk/core/graph.js +137 -137
  63. package/dist/formats/bnk/core/helpers.js +512 -480
  64. package/dist/formats/bnk/core/helpers.js.map +1 -1
  65. package/dist/formats/bnk/core/musicNodes.js +533 -509
  66. package/dist/formats/bnk/core/musicNodes.js.map +1 -1
  67. package/dist/formats/bnk/core/nodeBase.js +553 -532
  68. package/dist/formats/bnk/core/nodeBase.js.map +1 -1
  69. package/dist/formats/bnk/core/sfxNodes.js +632 -632
  70. package/dist/formats/bnk/core/soundbanksInfo.js +209 -209
  71. package/dist/formats/bnk/index.js +2 -2
  72. package/dist/formats/cmf/CjsCmfFormat.js +497 -497
  73. package/dist/formats/cmf/core/binary.js +194 -194
  74. package/dist/formats/cmf/core/buffers.js +237 -237
  75. package/dist/formats/cmf/core/constants.js +47 -47
  76. package/dist/formats/cmf/core/gr2Anim.js +453 -453
  77. package/dist/formats/cmf/core/helpers.js +318 -318
  78. package/dist/formats/cmf/core/pack.js +276 -276
  79. package/dist/formats/cmf/core/schema.js +374 -374
  80. package/dist/formats/cmf/core/shared.js +277 -277
  81. package/dist/formats/cmf/core/writer.js +571 -571
  82. package/dist/formats/cmf/index.js +2 -2
  83. package/dist/formats/dds/CjsDdsFormat.js +200 -200
  84. package/dist/formats/dds/core/bc6h.js +298 -298
  85. package/dist/formats/dds/core/bc7.js +272 -272
  86. package/dist/formats/dds/core/helpers.js +862 -862
  87. package/dist/formats/dds/index.js +2 -2
  88. package/dist/formats/dxbc/CjsDxbcFormat.js +142 -142
  89. package/dist/formats/dxbc/core/DxbcReader.js +266 -266
  90. package/dist/formats/dxbc/core/container.js +169 -169
  91. package/dist/formats/dxbc/core/decoder.js +789 -789
  92. package/dist/formats/dxbc/core/errors.js +19 -19
  93. package/dist/formats/dxbc/core/helpers.js +220 -220
  94. package/dist/formats/dxbc/core/opcodes.js +45 -45
  95. package/dist/formats/dxbc/core/program.js +91 -91
  96. package/dist/formats/dxbc/core/signature.js +172 -172
  97. package/dist/formats/dxbc/index.js +2 -2
  98. package/dist/formats/fbx/CjsFbxFormat.js +266 -266
  99. package/dist/formats/fbx/core/helpers.js +3932 -3932
  100. package/dist/formats/fbx/index.js +2 -2
  101. package/dist/formats/flac/CjsFlacFormat.js +142 -142
  102. package/dist/formats/flac/core/helpers.js +315 -315
  103. package/dist/formats/flac/index.js +2 -2
  104. package/dist/formats/gif/CjsGifFormat.js +141 -141
  105. package/dist/formats/gif/core/helpers.js +380 -380
  106. package/dist/formats/gif/index.js +2 -2
  107. package/dist/formats/gltf/CjsGltfFormat.js +290 -290
  108. package/dist/formats/gltf/core/helpers.js +307 -307
  109. package/dist/formats/gltf/core/json.js +79 -79
  110. package/dist/formats/gltf/core/parser.js +679 -679
  111. package/dist/formats/gltf/core/targets.js +173 -173
  112. package/dist/formats/gltf/index.js +2 -2
  113. package/dist/formats/gr2/CjsGr2Format.js +289 -289
  114. package/dist/formats/gr2/core/bitknit2.js +282 -282
  115. package/dist/formats/gr2/core/curves.js +1047 -1047
  116. package/dist/formats/gr2/core/gsf.js +72 -72
  117. package/dist/formats/gr2/core/helpers.js +352 -352
  118. package/dist/formats/gr2/core/json.js +622 -622
  119. package/dist/formats/gr2/core/oodle1.js +388 -388
  120. package/dist/formats/gr2/core/tangents.js +48 -48
  121. package/dist/formats/gr2/core/targets.js +361 -361
  122. package/dist/formats/gr2/index.js +2 -2
  123. package/dist/formats/hlsl/CjsHlslFormat.js +254 -254
  124. package/dist/formats/hlsl/core/HlslBinaryUtils.js +15 -15
  125. package/dist/formats/hlsl/core/HlslEffectReadError.js +19 -19
  126. package/dist/formats/hlsl/core/HlslEffectStateManager.js +130 -130
  127. package/dist/formats/hlsl/core/HlslRenderStateSetup.js +37 -37
  128. package/dist/formats/hlsl/core/HlslResourceSetDescription.js +94 -94
  129. package/dist/formats/hlsl/core/HlslShaderBytecode.js +44 -44
  130. package/dist/formats/hlsl/core/analysis.js +51 -51
  131. package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js +850 -781
  132. package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js.map +1 -1
  133. package/dist/formats/hlsl/core/detailMapFamily.js +128 -0
  134. package/dist/formats/hlsl/core/detailMapFamily.js.map +1 -0
  135. package/dist/formats/hlsl/core/helpers.js +270 -270
  136. package/dist/formats/hlsl/core/json.js +284 -284
  137. package/dist/formats/hlsl/core/localLightFamily.js +133 -0
  138. package/dist/formats/hlsl/core/localLightFamily.js.map +1 -0
  139. package/dist/formats/hlsl/core/metadata.js +327 -327
  140. package/dist/formats/hlsl/core/render-states.js +280 -280
  141. package/dist/formats/hlsl/core/tr2/HlslRenderContextEnum.js +43 -43
  142. package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js +320 -314
  143. package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js.map +1 -1
  144. package/dist/formats/hlsl/core/tr2/resources/HlslShaderPermutation.js +33 -33
  145. package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +416 -416
  146. package/dist/formats/hlsl/core/tr2/shader/HlslEffectConstant.js +40 -40
  147. package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js +62 -742
  148. package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js.map +1 -1
  149. package/dist/formats/hlsl/core/tr2/shader/HlslEffectLibrary.js +52 -52
  150. package/dist/formats/hlsl/core/tr2/shader/HlslEffectParameterAnnotation.js +38 -38
  151. package/dist/formats/hlsl/core/tr2/shader/HlslEffectResource.js +50 -50
  152. package/dist/formats/hlsl/core/tr2/shader/HlslEffectStageInput.js +86 -86
  153. package/dist/formats/hlsl/core/tr2/shader/HlslEffectTechnique.js +31 -31
  154. package/dist/formats/hlsl/core/tr2/shader/HlslPass.js +42 -42
  155. package/dist/formats/hlsl/core/tr2/shader/HlslSamplerDescription.js +55 -55
  156. package/dist/formats/hlsl/core/tr2/shader/HlslSamplerSetup.js +29 -29
  157. package/dist/formats/hlsl/core/tr2/shader/HlslShader.js +220 -220
  158. package/dist/formats/hlsl/core/tr2/shader/HlslShaderOption.js +30 -30
  159. package/dist/formats/hlsl/index.js +3 -3
  160. package/dist/formats/index.js +33 -31
  161. package/dist/formats/index.js.map +1 -1
  162. package/dist/formats/jpeg/CjsJpegFormat.js +212 -212
  163. package/dist/formats/jpeg/core/helpers.js +402 -402
  164. package/dist/formats/jpeg/core/jpeg.js +480 -480
  165. package/dist/formats/jpeg/index.js +2 -2
  166. package/dist/formats/mp3/CjsMp3Format.js +197 -197
  167. package/dist/formats/mp3/core/helpers.js +375 -375
  168. package/dist/formats/mp3/index.js +2 -2
  169. package/dist/formats/mp4/CjsMp4Format.js +197 -197
  170. package/dist/formats/mp4/core/helpers.js +484 -484
  171. package/dist/formats/mp4/index.js +2 -2
  172. package/dist/formats/obj/CjsObjFormat.js +253 -253
  173. package/dist/formats/obj/core/helpers.js +573 -573
  174. package/dist/formats/obj/core/json.js +64 -64
  175. package/dist/formats/obj/core/parser.js +321 -321
  176. package/dist/formats/obj/index.js +2 -2
  177. package/dist/formats/ogg/CjsOggFormat.js +143 -143
  178. package/dist/formats/ogg/core/helpers.js +410 -410
  179. package/dist/formats/ogg/core/imdct.js +178 -178
  180. package/dist/formats/ogg/core/vorbis.js +1017 -1017
  181. package/dist/formats/ogg/index.js +2 -2
  182. package/dist/formats/pickle/CjsPickleFormat.js +214 -0
  183. package/dist/formats/pickle/CjsPickleFormat.js.map +1 -0
  184. package/dist/formats/pickle/core/CjsPickleProtocol0Reader.js +551 -0
  185. package/dist/formats/pickle/core/CjsPickleProtocol0Reader.js.map +1 -0
  186. package/dist/formats/pickle/index.js +2 -0
  187. package/dist/formats/pickle/index.js.map +1 -0
  188. package/dist/formats/png/CjsPngFormat.js +201 -201
  189. package/dist/formats/png/core/helpers.js +635 -635
  190. package/dist/formats/png/index.js +2 -2
  191. package/dist/formats/red/CjsRedFormat.js +263 -263
  192. package/dist/formats/red/core/CjsRedReader.js +246 -246
  193. package/dist/formats/red/core/blackDefinitions.js +3 -3
  194. package/dist/formats/red/core/helpers.js +158 -158
  195. package/dist/formats/red/core/redGraph.js +71 -68
  196. package/dist/formats/red/core/redGraph.js.map +1 -1
  197. package/dist/formats/red/core/schema.js +4 -4
  198. package/dist/formats/red/index.js +2 -2
  199. package/dist/formats/stl/CjsStlFormat.js +365 -365
  200. package/dist/formats/stl/core/helpers.js +261 -261
  201. package/dist/formats/stl/core/json.js +51 -51
  202. package/dist/formats/stl/core/stl.js +642 -642
  203. package/dist/formats/stl/core/targets.js +173 -173
  204. package/dist/formats/stl/index.js +2 -2
  205. package/dist/formats/tga/CjsTgaFormat.js +197 -197
  206. package/dist/formats/tga/core/helpers.js +493 -493
  207. package/dist/formats/tga/index.js +2 -2
  208. package/dist/formats/wav/CjsWavFormat.js +198 -198
  209. package/dist/formats/wav/core/helpers.js +365 -365
  210. package/dist/formats/wav/index.js +2 -2
  211. package/dist/formats/webgl/CjsWebglFormat.js +199 -221
  212. package/dist/formats/webgl/CjsWebglFormat.js.map +1 -1
  213. package/dist/formats/webgl/core/buildGlslEffectContainer.js +70 -0
  214. package/dist/formats/webgl/core/buildGlslEffectContainer.js.map +1 -0
  215. package/dist/formats/webgl/core/effectPackage.js +900 -792
  216. package/dist/formats/webgl/core/effectPackage.js.map +1 -1
  217. package/dist/formats/webgl/core/errors.js +27 -27
  218. package/dist/formats/webgl/core/errors.js.map +1 -1
  219. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +2820 -2678
  220. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
  221. package/dist/formats/webgl/core/glsl/DxbcGlslHelpers.js +89 -89
  222. package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js +486 -428
  223. package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js.map +1 -1
  224. package/dist/formats/webgl/core/glsl/packedLightFixups.js +98 -0
  225. package/dist/formats/webgl/core/glsl/packedLightFixups.js.map +1 -0
  226. package/dist/formats/webgl/core/glslBackendBlock.js +552 -0
  227. package/dist/formats/webgl/core/glslBackendBlock.js.map +1 -0
  228. package/dist/formats/webgl/core/glslBackendBodySet.js +243 -0
  229. package/dist/formats/webgl/core/glslBackendBodySet.js.map +1 -0
  230. package/dist/formats/webgl/core/{cewgCompleteness.js → glslEffectCompleteness.js} +85 -81
  231. package/dist/formats/webgl/core/glslEffectCompleteness.js.map +1 -0
  232. package/dist/formats/webgl/core/helpers.js +167 -306
  233. package/dist/formats/webgl/core/helpers.js.map +1 -1
  234. package/dist/formats/webgl/core/inspectGlslEffectContainer.js +122 -0
  235. package/dist/formats/webgl/core/inspectGlslEffectContainer.js.map +1 -0
  236. package/dist/formats/webgl/core/readGlslEffectContainer.js +303 -0
  237. package/dist/formats/webgl/core/readGlslEffectContainer.js.map +1 -0
  238. package/dist/formats/webgl/index.js +2 -2
  239. package/dist/formats/webgpu/CjsWebgpuFormat.js +357 -357
  240. package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
  241. package/dist/formats/webgpu/core/buildCarbonEffectContainer.js +89 -197
  242. package/dist/formats/webgpu/core/buildCarbonEffectContainer.js.map +1 -1
  243. package/dist/formats/webgpu/core/{cewgpu/CewgpuContainer.js → carbonWebgpu/CarbonWebgpuContainer.js} +354 -368
  244. package/dist/formats/webgpu/core/carbonWebgpu/CarbonWebgpuContainer.js.map +1 -0
  245. package/dist/formats/webgpu/core/{cewgpu → carbonWebgpu}/containerViews.js +355 -355
  246. package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js.map +1 -0
  247. package/dist/formats/webgpu/core/{cewgpu → carbonWebgpu}/validateContainer.js +90 -90
  248. package/dist/formats/webgpu/core/carbonWebgpu/validateContainer.js.map +1 -0
  249. package/dist/formats/webgpu/core/effectAnalysis.js +82 -82
  250. package/dist/formats/webgpu/core/effectBackendBodySet.js +289 -289
  251. package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
  252. package/dist/formats/webgpu/core/errors.js +20 -20
  253. package/dist/formats/webgpu/core/errors.js.map +1 -1
  254. package/dist/formats/webgpu/core/helpers.js +443 -443
  255. package/dist/formats/webgpu/core/helpers.js.map +1 -1
  256. package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js +212 -212
  257. package/dist/formats/webgpu/core/ir/buildControlFlow.js +220 -220
  258. package/dist/formats/webgpu/core/ir/indexableTemps.js +137 -137
  259. package/dist/formats/webgpu/core/ir/inferValueTypes.js +449 -449
  260. package/dist/formats/webgpu/core/ir/lowerDxbcToIr.js +494 -494
  261. package/dist/formats/webgpu/core/ir/resolveRegisterFlow.js +177 -177
  262. package/dist/formats/webgpu/core/ir/sourceLanes.js +61 -61
  263. package/dist/formats/webgpu/core/packageEffect.js +381 -385
  264. package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
  265. package/dist/formats/webgpu/core/packageEffectSelection.js +164 -164
  266. package/dist/formats/webgpu/core/packageEffectSelection.js.map +1 -1
  267. package/dist/formats/webgpu/core/packageMetadata.js +17 -17
  268. package/dist/formats/webgpu/core/schema.js +4 -4
  269. package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +263 -263
  270. package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -1
  271. package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js +172 -172
  272. package/dist/formats/webgpu/core/wgsl/buildWgslSet.js +320 -320
  273. package/dist/formats/webgpu/core/wgsl/buildWgslSet.js.map +1 -1
  274. package/dist/formats/webgpu/core/wgsl/emitWgsl.js +356 -356
  275. package/dist/formats/webgpu/core/wgsl/hoistEscapingValues.js +77 -77
  276. package/dist/formats/webgpu/core/wgsl/lowerBindingLayout.js +451 -451
  277. package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js +735 -735
  278. package/dist/formats/webgpu/core/wgsl/lowerCreateHistogramsComputeProgram.js +457 -457
  279. package/dist/formats/webgpu/core/wgsl/lowerFragmentProgram.js +1572 -1572
  280. package/dist/formats/webgpu/core/wgsl/lowerMergeHistogramsComputeProgram.js +659 -659
  281. package/dist/formats/webgpu/core/wgsl/lowerParticleClearComputePrograms.js +734 -734
  282. package/dist/formats/webgpu/core/wgsl/lowerParticleEmitComputeProgram.js +583 -583
  283. package/dist/formats/webgpu/core/wgsl/lowerSkinVerticesComputeProgram.js +621 -621
  284. package/dist/formats/webgpu/core/wgsl/lowerSortComputeProgram.js +824 -824
  285. package/dist/formats/webgpu/core/wgsl/lowerSortInnerComputeProgram.js +697 -697
  286. package/dist/formats/webgpu/core/wgsl/lowerSortStepComputeProgram.js +559 -559
  287. package/dist/formats/webgpu/core/wgsl/lowerVertexProgram.js +1328 -1328
  288. package/dist/formats/webgpu/core/wgsl/particleEmitSemanticDigest.js +110 -110
  289. package/dist/formats/webgpu/core/wgsl/precisionControls.js +55 -55
  290. package/dist/formats/webgpu/core/wgsl/selectionPlans.js +717 -717
  291. package/dist/formats/webgpu/core/wgsl/uniformity.js +78 -78
  292. package/dist/formats/webgpu/core/wgsl/validateExactComputeIr.js +196 -196
  293. package/dist/formats/webgpu/core/wgsl/validateHandleOperand.js +37 -37
  294. package/dist/formats/webgpu/index.js +2 -2
  295. package/dist/formats/webm/CjsWebmFormat.js +197 -197
  296. package/dist/formats/webm/core/helpers.js +572 -572
  297. package/dist/formats/webm/index.js +2 -2
  298. package/dist/formats/webp/CjsWebpFormat.js +140 -140
  299. package/dist/formats/webp/core/helpers.js +237 -237
  300. package/dist/formats/webp/index.js +2 -2
  301. package/dist/formats/wem/CjsWemFormat.js +250 -250
  302. package/dist/formats/wem/core/bitStream.js +261 -261
  303. package/dist/formats/wem/core/codebookLibrary.js +164 -164
  304. package/dist/formats/wem/core/helpers.js +437 -437
  305. package/dist/formats/wem/core/packedCodebooksAotuv603.js +30 -30
  306. package/dist/formats/wem/core/ptadpcm.js +77 -77
  307. package/dist/formats/wem/core/resolve.js +121 -121
  308. package/dist/formats/wem/core/wemToOgg.js +485 -485
  309. package/dist/formats/wem/index.js +2 -2
  310. package/dist/formats/yaml/CjsYamlFormat.js +134 -134
  311. package/dist/formats/yaml/CjsYamlFormat.js.map +1 -1
  312. package/dist/formats/yaml/core/CjsYamlReader.js +400 -402
  313. package/dist/formats/yaml/core/CjsYamlReader.js.map +1 -1
  314. package/dist/formats/yaml/core/helpers.js +196 -170
  315. package/dist/formats/yaml/core/helpers.js.map +1 -1
  316. package/dist/formats/yaml/index.js +2 -2
  317. package/dist/index.js +64 -62
  318. package/dist/index.js.map +1 -1
  319. package/dist/resource/CjsLoadingObject.js +19 -0
  320. package/dist/resource/CjsLoadingObject.js.map +1 -0
  321. package/dist/resource/CjsResource.js +801 -797
  322. package/dist/resource/CjsResource.js.map +1 -1
  323. package/dist/resource/ResourceHandlerMode.js +14 -0
  324. package/dist/resource/ResourceHandlerMode.js.map +1 -0
  325. package/dist/resource/Tr2LightProfileRes.js +32 -32
  326. package/dist/resource/audio/AudioGeometryResData.js +47 -47
  327. package/dist/resource/audio/CjsAudioBufferRes.js +86 -86
  328. package/dist/resource/audio/CjsAudioRes.js +213 -213
  329. package/dist/resource/audio/index.js +4 -4
  330. package/dist/resource/geometry/MeshDecalData.js +37 -37
  331. package/dist/resource/geometry/MeshDecalLodData.js +34 -34
  332. package/dist/resource/geometry/TriGeometryRes.js +675 -675
  333. package/dist/resource/geometry/TriGeometryResAreaData.js +59 -59
  334. package/dist/resource/geometry/TriGeometryResJointData.js +38 -38
  335. package/dist/resource/geometry/TriGeometryResLodData.js +88 -88
  336. package/dist/resource/geometry/TriGeometryResMeshData.js +63 -63
  337. package/dist/resource/geometry/TriGeometryResSkeletonData.js +34 -34
  338. package/dist/resource/geometry/TriJointBinding.js +38 -38
  339. package/dist/resource/geometry/TriMorphTargetGeometryConstants.js +46 -46
  340. package/dist/resource/geometry/TriRtGeometryConstants.js +88 -88
  341. package/dist/resource/geometry/granny/GStateBindingCallbackData.js +31 -31
  342. package/dist/resource/geometry/granny/Tr2GrannyIntersectionResult.js +60 -60
  343. package/dist/resource/geometry/granny/Tr2GrannyStateRes.js +36 -36
  344. package/dist/resource/geometry/granny/TriGrannyRes.js +35 -35
  345. package/dist/resource/geometry/granny/enums.js +10 -10
  346. package/dist/resource/geometry/granny/index.js +6 -6
  347. package/dist/resource/geometry/index.js +17 -17
  348. package/dist/resource/index.js +54 -52
  349. package/dist/resource/index.js.map +1 -1
  350. package/dist/resource/resourceBoundary.js +64 -64
  351. package/dist/resource/shader/Tr2EffectRes.js +336 -431
  352. package/dist/resource/shader/Tr2EffectRes.js.map +1 -1
  353. package/dist/resource/shader/Tr2MaterialArea.js +31 -31
  354. package/dist/resource/shader/Tr2MaterialMesh.js +27 -27
  355. package/dist/resource/shader/Tr2MaterialRes.js +31 -31
  356. package/dist/resource/shader/Tr2Shader.js +283 -261
  357. package/dist/resource/shader/Tr2Shader.js.map +1 -1
  358. package/dist/resource/shader/Tr2ShaderPermutation.js +43 -43
  359. package/dist/resource/shader/index.js +17 -17
  360. package/dist/resource/shader/reflection/Tr2EffectConstant.js +143 -135
  361. package/dist/resource/shader/reflection/Tr2EffectConstant.js.map +1 -1
  362. package/dist/resource/shader/reflection/Tr2EffectDefine.js +30 -30
  363. package/dist/resource/shader/reflection/Tr2EffectDescription.js +114 -109
  364. package/dist/resource/shader/reflection/Tr2EffectDescription.js.map +1 -1
  365. package/dist/resource/shader/reflection/Tr2EffectLibrary.js +168 -147
  366. package/dist/resource/shader/reflection/Tr2EffectLibrary.js.map +1 -1
  367. package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js +125 -105
  368. package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js.map +1 -1
  369. package/dist/resource/shader/reflection/Tr2EffectResource.js +120 -86
  370. package/dist/resource/shader/reflection/Tr2EffectResource.js.map +1 -1
  371. package/dist/resource/shader/reflection/Tr2EffectStageInput.js +372 -241
  372. package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
  373. package/dist/resource/shader/reflection/Tr2EffectTechnique.js +78 -68
  374. package/dist/resource/shader/reflection/Tr2EffectTechnique.js.map +1 -1
  375. package/dist/resource/shader/reflection/Tr2Pass.js +168 -111
  376. package/dist/resource/shader/reflection/Tr2Pass.js.map +1 -1
  377. package/dist/resource/shader/reflection/carbonRecordFields.js +159 -0
  378. package/dist/resource/shader/reflection/carbonRecordFields.js.map +1 -0
  379. package/dist/resource/shader/reflection/shaderStage.js +22 -0
  380. package/dist/resource/shader/reflection/shaderStage.js.map +1 -0
  381. package/dist/resource/shader/sampler/Tr2SamplerSetup.js +135 -77
  382. package/dist/resource/shader/sampler/Tr2SamplerSetup.js.map +1 -1
  383. package/dist/resource/texture/CjsTextureArrayRes.js +472 -472
  384. package/dist/resource/texture/CjsTextureArrayResParameterProxy.js +179 -179
  385. package/dist/resource/texture/Tr2ImageRes.js +120 -120
  386. package/dist/resource/texture/Tr2TextureLodManager.js +82 -82
  387. package/dist/resource/texture/Tr2TextureLodUpdateRequest.js +37 -37
  388. package/dist/resource/texture/Tr2TexturePackChannel.js +37 -37
  389. package/dist/resource/texture/Tr2TexturePipeline.js +54 -54
  390. package/dist/resource/texture/Tr2TexturePipelineParams.js +34 -34
  391. package/dist/resource/texture/Tr2TexturePipelineStepCompress.js +40 -40
  392. package/dist/resource/texture/Tr2TexturePipelineStepGenerateMips.js +22 -22
  393. package/dist/resource/texture/Tr2TexturePipelineStepLimitSize.js +34 -34
  394. package/dist/resource/texture/Tr2TexturePipelineStepLoad.js +31 -31
  395. package/dist/resource/texture/Tr2TexturePipelineStepPack.js +43 -43
  396. package/dist/resource/texture/TriTextureRes.js +359 -359
  397. package/dist/resource/texture/index.js +15 -15
  398. package/dist/resource/texture/texturePipelineBehavior.js +308 -308
  399. package/dist/worker/CjsResManMainThreadLoader.js +89 -87
  400. package/dist/worker/CjsResManMainThreadLoader.js.map +1 -1
  401. package/dist/worker/CjsResManWorker.js +218 -217
  402. package/dist/worker/CjsResManWorker.js.map +1 -1
  403. package/dist/worker/CjsResManWorkerLoader.js +437 -434
  404. package/dist/worker/CjsResManWorkerLoader.js.map +1 -1
  405. package/dist/worker/protocol.js +12 -12
  406. package/docs/README.md +98 -98
  407. package/docs/architecture.md +118 -109
  408. package/docs/concepts/resource-lifecycle.md +226 -225
  409. package/docs/concepts/shader-resource-model.md +111 -114
  410. package/docs/concepts/writing-an-engine-adapter.md +115 -115
  411. package/docs/formats/README.md +138 -136
  412. package/docs/formats/carbon-effect-container.md +553 -452
  413. package/docs/formats/dxbc/README.md +68 -68
  414. package/docs/formats/dxbc/architecture.md +80 -80
  415. package/docs/formats/dxbc/reference/api.md +77 -77
  416. package/docs/formats/dxbc/reference/classes/README.md +9 -9
  417. package/docs/formats/dxbc/reference/decoded-output.md +122 -122
  418. package/docs/formats/gr2.md +160 -160
  419. package/docs/formats/hlsl/README.md +54 -54
  420. package/docs/formats/hlsl/architecture.md +65 -67
  421. package/docs/formats/hlsl/guides/hydrating-json-output.md +60 -62
  422. package/docs/formats/hlsl/guides/reading-effects.md +64 -64
  423. package/docs/formats/hlsl/reference/advanced-analysis.md +61 -66
  424. package/docs/formats/hlsl/reference/api.md +92 -98
  425. package/docs/formats/hlsl/reference/classes/README.md +11 -11
  426. package/docs/formats/hlsl/reference/json-graph.md +97 -100
  427. package/docs/formats/pickle.md +82 -0
  428. package/docs/formats/provenance.md +196 -196
  429. package/docs/formats/stl.md +37 -37
  430. package/docs/formats/webgl/README.md +115 -57
  431. package/docs/formats/webgl/architecture.md +69 -70
  432. package/docs/formats/webgl/carbon-constant-layouts.md +326 -326
  433. package/docs/formats/webgl/decl-io.md +1234 -1234
  434. package/docs/formats/webgl/memory-structured.md +890 -871
  435. package/docs/formats/webgl/reference/classes/README.md +9 -9
  436. package/docs/formats/webgl/texture-sample.md +964 -964
  437. package/docs/formats/webgpu/README.md +84 -84
  438. package/docs/formats/webgpu/architecture.md +95 -96
  439. package/docs/formats/webgpu/formats/{cewgpu.md → carbon-webgpu.md} +215 -216
  440. package/docs/formats/webgpu/guides/effect-packaging.md +189 -191
  441. package/docs/formats/webgpu/reference/api.md +196 -197
  442. package/docs/formats/webgpu/reference/classes/README.md +9 -9
  443. package/docs/formats/webgpu/reference/wgsl-compatibility.md +1546 -1543
  444. package/docs/formats/wwise.md +146 -85
  445. package/docs/reference/classes/README.md +35 -35
  446. package/docs/reference/classes/audio.md +30 -30
  447. package/docs/reference/classes/core.md +216 -206
  448. package/docs/reference/classes/dropped.md +46 -46
  449. package/docs/reference/classes/formats.md +944 -952
  450. package/docs/reference/classes/resources.md +456 -456
  451. package/docs/reference/classes/texture.md +26 -26
  452. package/docs/reference/events.md +117 -117
  453. package/docs/reference/motherlode-cache.md +275 -275
  454. package/docs/reference/queues.md +194 -110
  455. package/docs/reference/reload.md +107 -107
  456. package/docs/reference/texture-arrays.md +113 -113
  457. package/docs/reference/texture-pipeline.md +53 -53
  458. package/docs/reference/workers.md +142 -135
  459. package/docs/roadmap.md +150 -150
  460. package/format-notices/black/LICENSE +21 -21
  461. package/format-notices/black/NOTICE +47 -47
  462. package/format-notices/bnk/LICENSE +21 -21
  463. package/format-notices/bnk/NOTICE +21 -21
  464. package/format-notices/cmf/LICENSE +21 -21
  465. package/format-notices/cmf/NOTICE +36 -36
  466. package/format-notices/dds/LICENSE +21 -21
  467. package/format-notices/dds/NOTICE +14 -14
  468. package/format-notices/dxbc/LICENSE +21 -21
  469. package/format-notices/dxbc/NOTICE +20 -20
  470. package/format-notices/fbx/LICENSE +21 -21
  471. package/format-notices/fbx/NOTICE +14 -14
  472. package/format-notices/flac/LICENSE +21 -21
  473. package/format-notices/flac/NOTICE +14 -14
  474. package/format-notices/gif/LICENSE +21 -21
  475. package/format-notices/gif/NOTICE +14 -14
  476. package/format-notices/gltf/LICENSE +21 -21
  477. package/format-notices/gltf/NOTICE +27 -27
  478. package/format-notices/gr2/LICENSE +21 -21
  479. package/format-notices/gr2/NOTICE +60 -60
  480. package/format-notices/gr2/THIRD-PARTY-NOTICES.md +93 -93
  481. package/format-notices/hlsl/LICENSE +21 -21
  482. package/format-notices/hlsl/NOTICE +25 -25
  483. package/format-notices/jpeg/LICENSE +21 -21
  484. package/format-notices/jpeg/NOTICE +14 -14
  485. package/format-notices/mp3/LICENSE +21 -21
  486. package/format-notices/mp3/NOTICE +14 -14
  487. package/format-notices/mp4/LICENSE +21 -21
  488. package/format-notices/mp4/NOTICE +14 -14
  489. package/format-notices/obj/LICENSE +21 -21
  490. package/format-notices/obj/NOTICE +26 -26
  491. package/format-notices/ogg/LICENSE +21 -21
  492. package/format-notices/ogg/NOTICE +28 -28
  493. package/format-notices/png/LICENSE +21 -21
  494. package/format-notices/png/NOTICE +14 -14
  495. package/format-notices/red/LICENSE +21 -21
  496. package/format-notices/red/NOTICE +31 -31
  497. package/format-notices/stl/LICENSE +21 -21
  498. package/format-notices/stl/NOTICE +21 -21
  499. package/format-notices/tga/LICENSE +21 -21
  500. package/format-notices/tga/NOTICE +14 -14
  501. package/format-notices/wav/LICENSE +21 -21
  502. package/format-notices/wav/NOTICE +14 -14
  503. package/format-notices/webgl/LICENSE +21 -21
  504. package/format-notices/webgl/NOTICE +35 -35
  505. package/format-notices/webgpu/LICENSE +21 -21
  506. package/format-notices/webgpu/NOTICE +31 -31
  507. package/format-notices/webm/LICENSE +21 -21
  508. package/format-notices/webm/NOTICE +14 -14
  509. package/format-notices/webp/LICENSE +21 -21
  510. package/format-notices/webp/NOTICE +14 -14
  511. package/format-notices/wem/LICENSE +57 -57
  512. package/format-notices/wem/NOTICE +33 -33
  513. package/format-notices/yaml/LICENSE +21 -21
  514. package/format-notices/yaml/NOTICE +44 -44
  515. package/package.json +63 -63
  516. package/dist/format/carbonEffect/carbonDescriptionFromPortable.js +0 -372
  517. package/dist/format/carbonEffect/carbonDescriptionFromPortable.js.map +0 -1
  518. package/dist/format/effect/effectReflectionPackage.js +0 -636
  519. package/dist/format/effect/effectReflectionPackage.js.map +0 -1
  520. package/dist/formats/hlsl/core/HlslReader.js +0 -16
  521. package/dist/formats/hlsl/core/HlslReader.js.map +0 -1
  522. package/dist/formats/hlsl/core/portableReflection.js +0 -848
  523. package/dist/formats/hlsl/core/portableReflection.js.map +0 -1
  524. package/dist/formats/hlsl/portable.js +0 -2
  525. package/dist/formats/hlsl/portable.js.map +0 -1
  526. package/dist/formats/webgl/core/cewg/CewgPackage.js +0 -340
  527. package/dist/formats/webgl/core/cewg/CewgPackage.js.map +0 -1
  528. package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js +0 -104
  529. package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js.map +0 -1
  530. package/dist/formats/webgl/core/cewg/binary.js +0 -19
  531. package/dist/formats/webgl/core/cewg/binary.js.map +0 -1
  532. package/dist/formats/webgl/core/cewgCompleteness.js.map +0 -1
  533. package/dist/formats/webgl/core/effectPackageValidation.js +0 -331
  534. package/dist/formats/webgl/core/effectPackageValidation.js.map +0 -1
  535. package/dist/formats/webgpu/core/cewgpu/CewgpuContainer.js.map +0 -1
  536. package/dist/formats/webgpu/core/cewgpu/containerViews.js.map +0 -1
  537. package/dist/formats/webgpu/core/cewgpu/validateContainer.js.map +0 -1
  538. package/dist/resource/shader/portable.js +0 -33
  539. package/dist/resource/shader/portable.js.map +0 -1
  540. package/docs/formats/hlsl/reference/portable-reflection.md +0 -141
  541. 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