@carbonenginejs/runtime-resource 0.12.2 → 0.14.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 (238) hide show
  1. package/README.md +21 -0
  2. package/dist/CjsResMan.js +393 -29
  3. package/dist/CjsResMan.js.map +1 -1
  4. package/dist/format/carbonEffect/CjsCarbonEffectReader.js +165 -118
  5. package/dist/format/carbonEffect/CjsCarbonEffectReader.js.map +1 -1
  6. package/dist/format/carbonEffect/buildCarbonEffectContainer.js +182 -0
  7. package/dist/format/carbonEffect/buildCarbonEffectContainer.js.map +1 -0
  8. package/dist/format/carbonEffect/carbonEffectBackendBlock.js +7 -113
  9. package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -1
  10. package/dist/format/carbonEffect/carbonEffectRecords.js +258 -66
  11. package/dist/format/carbonEffect/carbonEffectRecords.js.map +1 -1
  12. package/dist/format/carbonEffect/carbonEffectResourceTransform.js +197 -0
  13. package/dist/format/carbonEffect/carbonEffectResourceTransform.js.map +1 -0
  14. package/dist/format/effect/effectBodyInventory.js +146 -0
  15. package/dist/format/effect/effectBodyInventory.js.map +1 -0
  16. package/dist/format/effect/effectPermutationGraph.js +13 -13
  17. package/dist/format/effect/effectPermutationGraph.js.map +1 -1
  18. package/dist/format/index.js +4 -4
  19. package/dist/formats/black/CjsBlackFormat.js +19 -1
  20. package/dist/formats/black/CjsBlackFormat.js.map +1 -1
  21. package/dist/formats/bnk/CjsBnkFormat.js +28 -9
  22. package/dist/formats/bnk/CjsBnkFormat.js.map +1 -1
  23. package/dist/formats/bnk/core/busNodes.js +252 -0
  24. package/dist/formats/bnk/core/busNodes.js.map +1 -0
  25. package/dist/formats/bnk/core/effectNodes.js +147 -0
  26. package/dist/formats/bnk/core/effectNodes.js.map +1 -0
  27. package/dist/formats/bnk/core/eventAction.js +135 -24
  28. package/dist/formats/bnk/core/eventAction.js.map +1 -1
  29. package/dist/formats/bnk/core/globalSettings.js +215 -0
  30. package/dist/formats/bnk/core/globalSettings.js.map +1 -0
  31. package/dist/formats/bnk/core/helpers.js +37 -5
  32. package/dist/formats/bnk/core/helpers.js.map +1 -1
  33. package/dist/formats/bnk/core/musicNodes.js +43 -19
  34. package/dist/formats/bnk/core/musicNodes.js.map +1 -1
  35. package/dist/formats/bnk/core/nodeBase.js +28 -7
  36. package/dist/formats/bnk/core/nodeBase.js.map +1 -1
  37. package/dist/formats/dds/core/helpers.js +40 -1
  38. package/dist/formats/dds/core/helpers.js.map +1 -1
  39. package/dist/formats/dxbc/CjsDxbcFormat.js +45 -0
  40. package/dist/formats/dxbc/CjsDxbcFormat.js.map +1 -1
  41. package/dist/formats/dxbc/core/disassemble.js +240 -0
  42. package/dist/formats/dxbc/core/disassemble.js.map +1 -0
  43. package/dist/formats/gltf/CjsGltfFormat.js +1 -39
  44. package/dist/formats/gltf/CjsGltfFormat.js.map +1 -1
  45. package/dist/formats/gltf/core/helpers.js +1 -21
  46. package/dist/formats/gltf/core/helpers.js.map +1 -1
  47. package/dist/formats/hlsl/CjsHlslFormat.js +0 -21
  48. package/dist/formats/hlsl/CjsHlslFormat.js.map +1 -1
  49. package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js +118 -49
  50. package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js.map +1 -1
  51. package/dist/formats/hlsl/core/detailMapFamily.js +128 -0
  52. package/dist/formats/hlsl/core/detailMapFamily.js.map +1 -0
  53. package/dist/formats/hlsl/core/localLightFamily.js +133 -0
  54. package/dist/formats/hlsl/core/localLightFamily.js.map +1 -0
  55. package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js +79 -73
  56. package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js.map +1 -1
  57. package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +8 -1
  58. package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js.map +1 -1
  59. package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js +11 -691
  60. package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js.map +1 -1
  61. package/dist/formats/index.js +4 -2
  62. package/dist/formats/index.js.map +1 -1
  63. package/dist/formats/obj/CjsObjFormat.js +1 -22
  64. package/dist/formats/obj/CjsObjFormat.js.map +1 -1
  65. package/dist/formats/obj/core/helpers.js +1 -21
  66. package/dist/formats/obj/core/helpers.js.map +1 -1
  67. package/dist/formats/pickle/CjsPickleFormat.js +214 -0
  68. package/dist/formats/pickle/CjsPickleFormat.js.map +1 -0
  69. package/dist/formats/pickle/core/CjsPickleProtocol0Reader.js +551 -0
  70. package/dist/formats/pickle/core/CjsPickleProtocol0Reader.js.map +1 -0
  71. package/dist/formats/pickle/index.js +2 -0
  72. package/dist/formats/pickle/index.js.map +1 -0
  73. package/dist/formats/red/core/redGraph.js +11 -8
  74. package/dist/formats/red/core/redGraph.js.map +1 -1
  75. package/dist/formats/stl/CjsStlFormat.js +1 -46
  76. package/dist/formats/stl/CjsStlFormat.js.map +1 -1
  77. package/dist/formats/stl/core/helpers.js +1 -21
  78. package/dist/formats/stl/core/helpers.js.map +1 -1
  79. package/dist/formats/webgl/CjsWebglFormat.js +33 -55
  80. package/dist/formats/webgl/CjsWebglFormat.js.map +1 -1
  81. package/dist/formats/webgl/core/buildGlslEffectContainer.js +70 -0
  82. package/dist/formats/webgl/core/buildGlslEffectContainer.js.map +1 -0
  83. package/dist/formats/webgl/core/effectPackage.js +216 -108
  84. package/dist/formats/webgl/core/effectPackage.js.map +1 -1
  85. package/dist/formats/webgl/core/errors.js +1 -1
  86. package/dist/formats/webgl/core/errors.js.map +1 -1
  87. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +166 -24
  88. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
  89. package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js +63 -5
  90. package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js.map +1 -1
  91. package/dist/formats/webgl/core/glsl/packedLightFixups.js +98 -0
  92. package/dist/formats/webgl/core/glsl/packedLightFixups.js.map +1 -0
  93. package/dist/formats/webgl/core/glslBackendBlock.js +552 -0
  94. package/dist/formats/webgl/core/glslBackendBlock.js.map +1 -0
  95. package/dist/formats/webgl/core/glslBackendBodySet.js +243 -0
  96. package/dist/formats/webgl/core/glslBackendBodySet.js.map +1 -0
  97. package/dist/formats/webgl/core/{cewgCompleteness.js → glslEffectCompleteness.js} +12 -8
  98. package/dist/formats/webgl/core/glslEffectCompleteness.js.map +1 -0
  99. package/dist/formats/webgl/core/helpers.js +33 -172
  100. package/dist/formats/webgl/core/helpers.js.map +1 -1
  101. package/dist/formats/webgl/core/inspectGlslEffectContainer.js +122 -0
  102. package/dist/formats/webgl/core/inspectGlslEffectContainer.js.map +1 -0
  103. package/dist/formats/webgl/core/readGlslEffectContainer.js +249 -0
  104. package/dist/formats/webgl/core/readGlslEffectContainer.js.map +1 -0
  105. package/dist/formats/webgpu/CjsWebgpuFormat.js +15 -15
  106. package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
  107. package/dist/formats/webgpu/core/buildCarbonEffectContainer.js +37 -145
  108. package/dist/formats/webgpu/core/buildCarbonEffectContainer.js.map +1 -1
  109. package/dist/formats/webgpu/core/{cewgpu/CewgpuContainer.js → carbonWebgpu/CarbonWebgpuContainer.js} +13 -27
  110. package/dist/formats/webgpu/core/carbonWebgpu/CarbonWebgpuContainer.js.map +1 -0
  111. package/dist/formats/webgpu/core/{cewgpu → carbonWebgpu}/containerViews.js +1 -1
  112. package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js.map +1 -0
  113. package/dist/formats/webgpu/core/{cewgpu → carbonWebgpu}/validateContainer.js +4 -4
  114. package/dist/formats/webgpu/core/carbonWebgpu/validateContainer.js.map +1 -0
  115. package/dist/formats/webgpu/core/effectBackendBodySet.js +18 -18
  116. package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
  117. package/dist/formats/webgpu/core/errors.js +1 -1
  118. package/dist/formats/webgpu/core/errors.js.map +1 -1
  119. package/dist/formats/webgpu/core/helpers.js +22 -22
  120. package/dist/formats/webgpu/core/helpers.js.map +1 -1
  121. package/dist/formats/webgpu/core/packageEffect.js +11 -15
  122. package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
  123. package/dist/formats/webgpu/core/packageEffectSelection.js +1 -1
  124. package/dist/formats/webgpu/core/packageEffectSelection.js.map +1 -1
  125. package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +23 -23
  126. package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -1
  127. package/dist/formats/webgpu/core/wgsl/buildWgslSet.js +6 -6
  128. package/dist/formats/webgpu/core/wgsl/buildWgslSet.js.map +1 -1
  129. package/dist/formats/yaml/CjsYamlFormat.js +3 -3
  130. package/dist/formats/yaml/CjsYamlFormat.js.map +1 -1
  131. package/dist/formats/yaml/core/CjsYamlReader.js +4 -6
  132. package/dist/formats/yaml/core/CjsYamlReader.js.map +1 -1
  133. package/dist/formats/yaml/core/helpers.js +27 -1
  134. package/dist/formats/yaml/core/helpers.js.map +1 -1
  135. package/dist/index.js +2 -0
  136. package/dist/index.js.map +1 -1
  137. package/dist/resource/CjsLoadingObject.js +19 -0
  138. package/dist/resource/CjsLoadingObject.js.map +1 -0
  139. package/dist/resource/CjsResource.js +4 -0
  140. package/dist/resource/CjsResource.js.map +1 -1
  141. package/dist/resource/ResourceHandlerMode.js +14 -0
  142. package/dist/resource/ResourceHandlerMode.js.map +1 -0
  143. package/dist/resource/index.js +2 -0
  144. package/dist/resource/index.js.map +1 -1
  145. package/dist/resource/shader/Tr2EffectRes.js +118 -213
  146. package/dist/resource/shader/Tr2EffectRes.js.map +1 -1
  147. package/dist/resource/shader/Tr2Shader.js +37 -15
  148. package/dist/resource/shader/Tr2Shader.js.map +1 -1
  149. package/dist/resource/shader/reflection/Tr2EffectConstant.js +37 -29
  150. package/dist/resource/shader/reflection/Tr2EffectConstant.js.map +1 -1
  151. package/dist/resource/shader/reflection/Tr2EffectDescription.js +39 -34
  152. package/dist/resource/shader/reflection/Tr2EffectDescription.js.map +1 -1
  153. package/dist/resource/shader/reflection/Tr2EffectLibrary.js +51 -30
  154. package/dist/resource/shader/reflection/Tr2EffectLibrary.js.map +1 -1
  155. package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js +45 -25
  156. package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js.map +1 -1
  157. package/dist/resource/shader/reflection/Tr2EffectResource.js +51 -17
  158. package/dist/resource/shader/reflection/Tr2EffectResource.js.map +1 -1
  159. package/dist/resource/shader/reflection/Tr2EffectStageInput.js +219 -88
  160. package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
  161. package/dist/resource/shader/reflection/Tr2EffectTechnique.js +28 -18
  162. package/dist/resource/shader/reflection/Tr2EffectTechnique.js.map +1 -1
  163. package/dist/resource/shader/reflection/Tr2Pass.js +96 -39
  164. package/dist/resource/shader/reflection/Tr2Pass.js.map +1 -1
  165. package/dist/resource/shader/reflection/carbonRecordFields.js +159 -0
  166. package/dist/resource/shader/reflection/carbonRecordFields.js.map +1 -0
  167. package/dist/resource/shader/reflection/shaderStage.js +22 -0
  168. package/dist/resource/shader/reflection/shaderStage.js.map +1 -0
  169. package/dist/resource/shader/sampler/Tr2SamplerSetup.js +68 -10
  170. package/dist/resource/shader/sampler/Tr2SamplerSetup.js.map +1 -1
  171. package/dist/worker/CjsResManMainThreadLoader.js +9 -7
  172. package/dist/worker/CjsResManMainThreadLoader.js.map +1 -1
  173. package/dist/worker/CjsResManWorker.js +5 -4
  174. package/dist/worker/CjsResManWorker.js.map +1 -1
  175. package/dist/worker/CjsResManWorkerLoader.js +9 -6
  176. package/dist/worker/CjsResManWorkerLoader.js.map +1 -1
  177. package/docs/README.md +2 -2
  178. package/docs/architecture.md +12 -3
  179. package/docs/concepts/resource-lifecycle.md +9 -8
  180. package/docs/concepts/shader-resource-model.md +14 -17
  181. package/docs/concepts/writing-an-engine-adapter.md +1 -1
  182. package/docs/formats/README.md +4 -2
  183. package/docs/formats/carbon-effect-container.md +127 -26
  184. package/docs/formats/dxbc/architecture.md +1 -1
  185. package/docs/formats/dxbc/reference/api.md +28 -0
  186. package/docs/formats/hlsl/README.md +3 -3
  187. package/docs/formats/hlsl/architecture.md +8 -9
  188. package/docs/formats/hlsl/guides/hydrating-json-output.md +3 -5
  189. package/docs/formats/hlsl/guides/reading-effects.md +5 -1
  190. package/docs/formats/hlsl/reference/advanced-analysis.md +20 -25
  191. package/docs/formats/hlsl/reference/api.md +0 -7
  192. package/docs/formats/hlsl/reference/json-graph.md +1 -4
  193. package/docs/formats/pickle.md +82 -0
  194. package/docs/formats/webgl/README.md +71 -13
  195. package/docs/formats/webgl/architecture.md +16 -17
  196. package/docs/formats/webgl/carbon-constant-layouts.md +3 -3
  197. package/docs/formats/webgl/decl-io.md +3 -3
  198. package/docs/formats/webgl/memory-structured.md +27 -8
  199. package/docs/formats/webgl/texture-sample.md +1 -1
  200. package/docs/formats/webgpu/README.md +3 -3
  201. package/docs/formats/webgpu/architecture.md +5 -6
  202. package/docs/formats/webgpu/formats/{cewgpu.md → carbon-webgpu.md} +10 -11
  203. package/docs/formats/webgpu/guides/effect-packaging.md +6 -8
  204. package/docs/formats/webgpu/reference/api.md +11 -12
  205. package/docs/formats/webgpu/reference/wgsl-compatibility.md +11 -8
  206. package/docs/formats/wwise.md +63 -2
  207. package/docs/reference/classes/core.md +10 -0
  208. package/docs/reference/classes/formats.md +40 -48
  209. package/docs/reference/classes/resources.md +2 -2
  210. package/docs/reference/queues.md +88 -4
  211. package/docs/reference/workers.md +7 -0
  212. package/package.json +61 -61
  213. package/dist/format/carbonEffect/carbonDescriptionFromPortable.js +0 -372
  214. package/dist/format/carbonEffect/carbonDescriptionFromPortable.js.map +0 -1
  215. package/dist/format/effect/effectReflectionPackage.js +0 -636
  216. package/dist/format/effect/effectReflectionPackage.js.map +0 -1
  217. package/dist/formats/hlsl/core/HlslReader.js +0 -16
  218. package/dist/formats/hlsl/core/HlslReader.js.map +0 -1
  219. package/dist/formats/hlsl/core/portableReflection.js +0 -848
  220. package/dist/formats/hlsl/core/portableReflection.js.map +0 -1
  221. package/dist/formats/hlsl/portable.js +0 -2
  222. package/dist/formats/hlsl/portable.js.map +0 -1
  223. package/dist/formats/webgl/core/cewg/CewgPackage.js +0 -340
  224. package/dist/formats/webgl/core/cewg/CewgPackage.js.map +0 -1
  225. package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js +0 -104
  226. package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js.map +0 -1
  227. package/dist/formats/webgl/core/cewg/binary.js +0 -19
  228. package/dist/formats/webgl/core/cewg/binary.js.map +0 -1
  229. package/dist/formats/webgl/core/cewgCompleteness.js.map +0 -1
  230. package/dist/formats/webgl/core/effectPackageValidation.js +0 -331
  231. package/dist/formats/webgl/core/effectPackageValidation.js.map +0 -1
  232. package/dist/formats/webgpu/core/cewgpu/CewgpuContainer.js.map +0 -1
  233. package/dist/formats/webgpu/core/cewgpu/containerViews.js.map +0 -1
  234. package/dist/formats/webgpu/core/cewgpu/validateContainer.js.map +0 -1
  235. package/dist/resource/shader/portable.js +0 -33
  236. package/dist/resource/shader/portable.js.map +0 -1
  237. package/docs/formats/hlsl/reference/portable-reflection.md +0 -141
  238. package/docs/formats/webgl/effect-reflection.md +0 -127
@@ -1,47 +1,20 @@
1
1
  import '../../../format/compareUtf8.js';
2
2
  import { writeBackendBlock } from '../../../format/carbonEffect/carbonEffectBackendBlock.js';
3
- import { carbonDescriptionFromPortable } from '../../../format/carbonEffect/carbonDescriptionFromPortable.js';
4
3
  import '../../../format/CjsByteReader.js';
5
- import { CjsCarbonEffectWriter } from '../../../format/carbonEffect/CjsCarbonEffectWriter.js';
6
- import { buildEffectBodyReflection } from '../../hlsl/core/portableReflection.js';
4
+ import '../../../format/carbonEffect/CjsCarbonEffectWriter.js';
5
+ import { buildCarbonEffectContainer as buildCarbonEffectContainer$1 } from '../../../format/carbonEffect/buildCarbonEffectContainer.js';
7
6
 
8
7
  /**
9
- * Assembles the WebGPU effect container: Carbon's v15 record layout carrying
10
- * WGSL where a shipped file carries DXBC.
8
+ * The WebGPU backend adapter for the shared Carbon container builder.
11
9
  *
12
- * The Carbon record layout is shared across backends. CEWGPU replaces stage
13
- * program bytes with WGSL or an empty slot and adds one optional trailing block
14
- * per pass. The portable-to-Carbon mapping retains representable non-program
15
- * fields; non-dynamic sampler names are unrecoverable and stage order is
16
- * canonicalized.
17
- */
18
-
19
- /**
20
- * There is no envelope, no magic and no version of our own. That is deliberate.
21
- *
22
- * A twelve-byte prefix (`magic | containerVersion | payloadKind`) was carried
23
- * here and has been removed, along with a proposed "v16" for this variant.
24
- * Neither survived the only question worth asking of an addition: what breaks
25
- * without it?
10
+ * Everything about the record layout, the permutation walk and the description
11
+ * mapping lives in `format/carbonEffect/buildCarbonEffectContainer.js` and is
12
+ * shared with WebGL. What remains here is the two things that are genuinely
13
+ * WGSL: how a program becomes bytes, and what a pass's trailing block contains.
26
14
  *
27
- * - `payloadKind` is redundant with the directory the file came from. CEWGPU
28
- * identity belongs to the `effect.webgpu/` resource path; `.cewg` remains a
29
- * separate CEWG chunk format.
30
- * - The magic only distinguished our file from a Carbon one, which the same
31
- * directory already answers, and which the file *name* answers too.
32
- * - A version of our own would have claimed a number CCP owns, in the one field
33
- * whose job is telling a reader how to parse. A real v16 from them would then
34
- * collide with ours.
35
- *
36
- * What remains is a bare Carbon v15 record file. `CewgpuContainer` reads it and
37
- * the shared record reader detects the per-pass block from the description's
38
- * declared end. Direct `Tr2EffectRes` hydration remains an adapter boundary:
39
- * a Carbon description tree is not the portable reflection envelope consumed
40
- * by `Tr2Shader.fromPortable`.
41
- *
42
- * The one addition that does survive the question is the block itself: WebGPU
43
- * bind-group layouts come from the lowered IR and are not derivable from Carbon
44
- * reflection, so without it there is no binding topology and no pipeline.
15
+ * The block carries bind-group layouts and resource transforms. Neither is
16
+ * derivable from Carbon reflection - Carbon records the D3D binding model, while
17
+ * `(group, binding, visibility, generatedSymbol)` comes from the lowered IR.
45
18
  */
46
19
 
47
20
  /**
@@ -57,6 +30,24 @@ import { buildEffectBodyReflection } from '../../hlsl/core/portableReflection.js
57
30
  */
58
31
  const WGSL_ENTRY_POINT = "main";
59
32
 
33
+ /**
34
+ * Encodes one WGSL stage program.
35
+ *
36
+ * `sourceMap` is deliberately dropped. Its offsets index DXBC bytes, which this
37
+ * container does not carry, so it is a translator diagnostic rather than
38
+ * payload. It was separately measured to suppress no sharing, so keeping it
39
+ * would buy nothing either.
40
+ *
41
+ * @param {object} shader Translated shader record.
42
+ * @returns {Uint8Array} Program bytes.
43
+ */
44
+ function encodeProgram(shader) {
45
+ if (shader.entryPoint !== WGSL_ENTRY_POINT) {
46
+ throw new Error(`WGSL shader ${shader.key} has entry point "${shader.entryPoint}"; ` + `the container omits the name because every lowerer emits "${WGSL_ENTRY_POINT}"`);
47
+ }
48
+ return new TextEncoder().encode(shader.code);
49
+ }
50
+
60
51
  /**
61
52
  * Builds the per-pass backend block for one pass of one translated body.
62
53
  *
@@ -64,7 +55,7 @@ const WGSL_ENTRY_POINT = "main";
64
55
  * @param {string} passKey Enclosing pass key.
65
56
  * @returns {Uint8Array|null} Block bytes, or null when the pass has no layout.
66
57
  */
67
- function backendBlockFor(unit, passKey) {
58
+ function encodeBackendBlock(unit, passKey) {
68
59
  const layout = unit.layouts.find(entry => entry.key === passKey);
69
60
  if (!layout) return null;
70
61
  return writeBackendBlock({
@@ -73,73 +64,11 @@ function backendBlockFor(unit, passKey) {
73
64
  });
74
65
  }
75
66
 
76
- /**
77
- * Maps one body's translated passes by pass key.
78
- *
79
- * @param {object} body Backend body-set record.
80
- * @param {Map<string, object>} unitsByKey Units indexed by key.
81
- * @returns {Map<string, object>} Units indexed by pass key.
82
- */
83
- function unitsByPassKey(body, unitsByKey) {
84
- const result = new Map();
85
- for (const pass of body.passes ?? []) {
86
- result.set(pass.passKey, unitsByKey.get(pass.unitKey));
87
- }
88
- return result;
89
- }
90
-
91
- /**
92
- * Builds one body's Carbon description record tree with WGSL substituted in.
93
- *
94
- * A body the translator could not lower retains its representable non-program
95
- * description fields and carries zero-length programs. Emitting empty
96
- * `shaderData` says exactly what the wire knows: no backend program was stored.
97
- * Full portable source reflection remains in the in-memory build result, not
98
- * in this emitted body.
99
- *
100
- * @param {object} effectRes Loaded version-15 `Tr2EffectRes`.
101
- * @param {number} permutationIndex Representative permutation for this body.
102
- * @param {Map<string, object>|null} passUnits Units by pass key, or null when unsupported.
103
- * @returns {object} Description record tree.
104
- */
105
- function describeBody(effectRes, permutationIndex, passUnits) {
106
- const reflection = buildEffectBodyReflection(effectRes, permutationIndex);
107
- if (!passUnits) {
108
- return carbonDescriptionFromPortable(reflection, {
109
- programFor: () => ({
110
- bytes: new Uint8Array(0),
111
- size: 0
112
- })
113
- });
114
- }
115
- return carbonDescriptionFromPortable(reflection, {
116
- programFor: (stage, context) => {
117
- const unit = passUnits.get(context.passKey);
118
- const shader = unit?.shaders.find(entry => entry.key === `${context.passKey}.${stage.stageName}`);
119
- if (!shader) return {
120
- bytes: new Uint8Array(0),
121
- size: 0
122
- };
123
- if (shader.entryPoint !== WGSL_ENTRY_POINT) {
124
- throw new Error(`WGSL shader ${shader.key} has entry point "${shader.entryPoint}"; ` + `the container omits the name because every lowerer emits "${WGSL_ENTRY_POINT}"`);
125
- }
126
-
127
- // `sourceMap` is deliberately dropped. Its offsets index DXBC bytes,
128
- // which this container does not carry, so it is a translator
129
- // diagnostic rather than payload. It was separately measured to
130
- // suppress no sharing, so keeping it would buy nothing either.
131
- const bytes = new TextEncoder().encode(shader.code);
132
- return {
133
- bytes,
134
- size: bytes.byteLength
135
- };
136
- },
137
- backendBlockFor: context => {
138
- const unit = passUnits.get(context.passKey);
139
- return unit ? backendBlockFor(unit, context.passKey) : null;
140
- }
141
- });
142
- }
67
+ /** The WebGPU encoders, as the shared builder's backend argument. */
68
+ const WGSL_CONTAINER_BACKEND = Object.freeze({
69
+ encodeProgram,
70
+ encodeBackendBlock
71
+ });
143
72
 
144
73
  /**
145
74
  * Builds the complete WebGPU effect container.
@@ -150,48 +79,11 @@ function describeBody(effectRes, permutationIndex, passUnits) {
150
79
  * @param {object} [options] Container options.
151
80
  * @param {number[]|Uint8Array} [options.compilerVersion] Four version bytes.
152
81
  * @param {string} [options.sourceHash] 32 ASCII hash characters.
153
- * @returns {{bytes:Uint8Array, bodyCount:number, distinctBodyCount:number}} Container and its body accounting.
82
+ * @returns {{bytes:Uint8Array, permutationCount:number, bodyCount:number}} Container and its body accounting.
154
83
  */
155
84
  function buildCarbonEffectContainer(effectRes, permutationGraph, backendBodySet, options = {}) {
156
- const unitsByKey = new Map(backendBodySet.passUnits.map(unit => [unit.key, unit]));
157
- const bodyByKey = new Map(backendBodySet.bodies.map(body => [body.bodyKey, body]));
158
- const writer = new CjsCarbonEffectWriter({
159
- backend: true,
160
- compilerVersion: options.compilerVersion ?? effectRes.m_compilerVersionBytes ?? [0, 0, 0, 0],
161
- ...(options.sourceHash ? {
162
- sourceHash: options.sourceHash
163
- } : {})
164
- });
165
- for (const axis of permutationGraph.axes) {
166
- writer.addPermutation({
167
- name: axis.name,
168
- defaultOption: axis.defaultOption,
169
- description: axis.description,
170
- type: axis.type,
171
- options: axis.options
172
- });
173
- }
174
-
175
- // Build one emitted description per source body key and reuse it for each
176
- // matching permutation. The writer may dedupe additional descriptions when
177
- // their emitted bytes become identical after source programs are replaced;
178
- // the offset table remains dense.
179
- const describedByBodyKey = new Map();
180
- for (const [permutationIndex, variant] of permutationGraph.variants.entries()) {
181
- let description = describedByBodyKey.get(variant.bodyKey);
182
- if (!description) {
183
- const body = bodyByKey.get(variant.bodyKey);
184
- description = describeBody(effectRes, body?.representativePermutationIndex ?? permutationIndex, body?.status === "translated" ? unitsByPassKey(body, unitsByKey) : null);
185
- describedByBodyKey.set(variant.bodyKey, description);
186
- }
187
- writer.addBody(permutationIndex, description);
188
- }
189
- return {
190
- bytes: writer.toBytes(),
191
- permutationCount: permutationGraph.variants.length,
192
- bodyCount: describedByBodyKey.size
193
- };
85
+ return buildCarbonEffectContainer$1(effectRes, permutationGraph, backendBodySet, WGSL_CONTAINER_BACKEND, options);
194
86
  }
195
87
 
196
- export { WGSL_ENTRY_POINT, buildCarbonEffectContainer };
88
+ export { WGSL_CONTAINER_BACKEND, WGSL_ENTRY_POINT, buildCarbonEffectContainer };
197
89
  //# sourceMappingURL=buildCarbonEffectContainer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"buildCarbonEffectContainer.js","sources":["../../../../../src/formats/webgpu/core/buildCarbonEffectContainer.js"],"sourcesContent":["import {\n CjsCarbonEffectWriter,\n carbonDescriptionFromPortable,\n writeBackendBlock\n} from \"../../../format/carbonEffect/index.js\";\nimport { buildEffectBodyReflection } from \"../../hlsl/core/portableReflection.js\";\n\n/**\n * Assembles the WebGPU effect container: Carbon's v15 record layout carrying\n * WGSL where a shipped file carries DXBC.\n *\n * The Carbon record layout is shared across backends. CEWGPU replaces stage\n * program bytes with WGSL or an empty slot and adds one optional trailing block\n * per pass. The portable-to-Carbon mapping retains representable non-program\n * fields; non-dynamic sampler names are unrecoverable and stage order is\n * canonicalized.\n */\n\n/**\n * There is no envelope, no magic and no version of our own. That is deliberate.\n *\n * A twelve-byte prefix (`magic | containerVersion | payloadKind`) was carried\n * here and has been removed, along with a proposed \"v16\" for this variant.\n * Neither survived the only question worth asking of an addition: what breaks\n * without it?\n *\n * - `payloadKind` is redundant with the directory the file came from. CEWGPU\n * identity belongs to the `effect.webgpu/` resource path; `.cewg` remains a\n * separate CEWG chunk format.\n * - The magic only distinguished our file from a Carbon one, which the same\n * directory already answers, and which the file *name* answers too.\n * - A version of our own would have claimed a number CCP owns, in the one field\n * whose job is telling a reader how to parse. A real v16 from them would then\n * collide with ours.\n *\n * What remains is a bare Carbon v15 record file. `CewgpuContainer` reads it and\n * the shared record reader detects the per-pass block from the description's\n * declared end. Direct `Tr2EffectRes` hydration remains an adapter boundary:\n * a Carbon description tree is not the portable reflection envelope consumed\n * by `Tr2Shader.fromPortable`.\n *\n * The one addition that does survive the question is the block itself: WebGPU\n * bind-group layouts come from the lowered IR and are not derivable from Carbon\n * reflection, so without it there is no binding topology and no pipeline.\n */\n\n/**\n * The entry-point name every WGSL lowerer emits.\n *\n * Carbon's `StageInput` has no entry-point field, so the container can only omit\n * one if it is a constant of our emitter rather than data. It is: all thirteen\n * `lower*Program` modules write `entryPoint: \"main\"` literally. Measured constant\n * across 626 shaders in seven effects — but measurement only shows it holds\n * today, so the substitution asserts it. A future lowerer that picks a different\n * name fails the build instead of silently emitting a container whose programs\n * cannot be found.\n */\nexport const WGSL_ENTRY_POINT = \"main\";\n\n/**\n * Builds the per-pass backend block for one pass of one translated body.\n *\n * @param {object} unit Pass translation unit.\n * @param {string} passKey Enclosing pass key.\n * @returns {Uint8Array|null} Block bytes, or null when the pass has no layout.\n */\nfunction backendBlockFor(unit, passKey)\n{\n const layout = unit.layouts.find((entry) => entry.key === passKey);\n if (!layout) return null;\n\n return writeBackendBlock({\n bindGroups: layout.bindGroups,\n transforms: (unit.resourceTransforms ?? [])\n .filter((transform) => transform.layoutKey === passKey)\n });\n}\n\n/**\n * Maps one body's translated passes by pass key.\n *\n * @param {object} body Backend body-set record.\n * @param {Map<string, object>} unitsByKey Units indexed by key.\n * @returns {Map<string, object>} Units indexed by pass key.\n */\nfunction unitsByPassKey(body, unitsByKey)\n{\n const result = new Map();\n for (const pass of body.passes ?? [])\n {\n result.set(pass.passKey, unitsByKey.get(pass.unitKey));\n }\n return result;\n}\n\n/**\n * Builds one body's Carbon description record tree with WGSL substituted in.\n *\n * A body the translator could not lower retains its representable non-program\n * description fields and carries zero-length programs. Emitting empty\n * `shaderData` says exactly what the wire knows: no backend program was stored.\n * Full portable source reflection remains in the in-memory build result, not\n * in this emitted body.\n *\n * @param {object} effectRes Loaded version-15 `Tr2EffectRes`.\n * @param {number} permutationIndex Representative permutation for this body.\n * @param {Map<string, object>|null} passUnits Units by pass key, or null when unsupported.\n * @returns {object} Description record tree.\n */\nfunction describeBody(effectRes, permutationIndex, passUnits)\n{\n const reflection = buildEffectBodyReflection(effectRes, permutationIndex);\n\n if (!passUnits)\n {\n return carbonDescriptionFromPortable(reflection, {\n programFor: () => ({ bytes: new Uint8Array(0), size: 0 })\n });\n }\n\n return carbonDescriptionFromPortable(reflection, {\n programFor: (stage, context) =>\n {\n const unit = passUnits.get(context.passKey);\n const shader = unit?.shaders.find(\n (entry) => entry.key === `${context.passKey}.${stage.stageName}`\n );\n\n if (!shader) return { bytes: new Uint8Array(0), size: 0 };\n\n if (shader.entryPoint !== WGSL_ENTRY_POINT)\n {\n throw new Error(\n `WGSL shader ${shader.key} has entry point \"${shader.entryPoint}\"; `\n + `the container omits the name because every lowerer emits \"${WGSL_ENTRY_POINT}\"`\n );\n }\n\n // `sourceMap` is deliberately dropped. Its offsets index DXBC bytes,\n // which this container does not carry, so it is a translator\n // diagnostic rather than payload. It was separately measured to\n // suppress no sharing, so keeping it would buy nothing either.\n const bytes = new TextEncoder().encode(shader.code);\n return { bytes, size: bytes.byteLength };\n },\n backendBlockFor: (context) =>\n {\n const unit = passUnits.get(context.passKey);\n return unit ? backendBlockFor(unit, context.passKey) : null;\n }\n });\n}\n\n/**\n * Builds the complete WebGPU effect container.\n *\n * @param {object} effectRes Loaded version-15 `Tr2EffectRes`.\n * @param {object} permutationGraph Validated `PGRF` document.\n * @param {object} backendBodySet Translated backend bodies.\n * @param {object} [options] Container options.\n * @param {number[]|Uint8Array} [options.compilerVersion] Four version bytes.\n * @param {string} [options.sourceHash] 32 ASCII hash characters.\n * @returns {{bytes:Uint8Array, bodyCount:number, distinctBodyCount:number}} Container and its body accounting.\n */\nexport function buildCarbonEffectContainer(\n effectRes,\n permutationGraph,\n backendBodySet,\n options = {}\n)\n{\n const unitsByKey = new Map(backendBodySet.passUnits.map((unit) => [ unit.key, unit ]));\n const bodyByKey = new Map(backendBodySet.bodies.map((body) => [ body.bodyKey, body ]));\n const writer = new CjsCarbonEffectWriter({\n backend: true,\n compilerVersion: options.compilerVersion ?? effectRes.m_compilerVersionBytes ?? [ 0, 0, 0, 0 ],\n ...(options.sourceHash ? { sourceHash: options.sourceHash } : {})\n });\n\n for (const axis of permutationGraph.axes)\n {\n writer.addPermutation({\n name: axis.name,\n defaultOption: axis.defaultOption,\n description: axis.description,\n type: axis.type,\n options: axis.options\n });\n }\n\n // Build one emitted description per source body key and reuse it for each\n // matching permutation. The writer may dedupe additional descriptions when\n // their emitted bytes become identical after source programs are replaced;\n // the offset table remains dense.\n const describedByBodyKey = new Map();\n\n for (const [ permutationIndex, variant ] of permutationGraph.variants.entries())\n {\n let description = describedByBodyKey.get(variant.bodyKey);\n\n if (!description)\n {\n const body = bodyByKey.get(variant.bodyKey);\n description = describeBody(\n effectRes,\n body?.representativePermutationIndex ?? permutationIndex,\n body?.status === \"translated\" ? unitsByPassKey(body, unitsByKey) : null\n );\n describedByBodyKey.set(variant.bodyKey, description);\n }\n\n writer.addBody(permutationIndex, description);\n }\n\n return {\n bytes: writer.toBytes(),\n permutationCount: permutationGraph.variants.length,\n bodyCount: describedByBodyKey.size\n };\n}\n\nexport default buildCarbonEffectContainer;\n"],"names":["WGSL_ENTRY_POINT","backendBlockFor","unit","passKey","layout","layouts","find","entry","key","writeBackendBlock","bindGroups","transforms","resourceTransforms","filter","transform","layoutKey","unitsByPassKey","body","unitsByKey","result","Map","pass","passes","set","get","unitKey","describeBody","effectRes","permutationIndex","passUnits","reflection","buildEffectBodyReflection","carbonDescriptionFromPortable","programFor","bytes","Uint8Array","size","stage","context","shader","shaders","stageName","entryPoint","Error","TextEncoder","encode","code","byteLength","buildCarbonEffectContainer","permutationGraph","backendBodySet","options","map","bodyByKey","bodies","bodyKey","writer","CjsCarbonEffectWriter","backend","compilerVersion","m_compilerVersionBytes","sourceHash","axis","axes","addPermutation","name","defaultOption","description","type","describedByBodyKey","variant","variants","entries","representativePermutationIndex","status","addBody","toBytes","permutationCount","length","bodyCount"],"mappings":"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"}
1
+ {"version":3,"file":"buildCarbonEffectContainer.js","sources":["../../../../../src/formats/webgpu/core/buildCarbonEffectContainer.js"],"sourcesContent":["import { writeBackendBlock } from \"../../../format/carbonEffect/index.js\";\nimport {\n buildCarbonEffectContainer as buildContainer\n} from \"../../../format/carbonEffect/buildCarbonEffectContainer.js\";\n\n/**\n * The WebGPU backend adapter for the shared Carbon container builder.\n *\n * Everything about the record layout, the permutation walk and the description\n * mapping lives in `format/carbonEffect/buildCarbonEffectContainer.js` and is\n * shared with WebGL. What remains here is the two things that are genuinely\n * WGSL: how a program becomes bytes, and what a pass's trailing block contains.\n *\n * The block carries bind-group layouts and resource transforms. Neither is\n * derivable from Carbon reflection - Carbon records the D3D binding model, while\n * `(group, binding, visibility, generatedSymbol)` comes from the lowered IR.\n */\n\n/**\n * The entry-point name every WGSL lowerer emits.\n *\n * Carbon's `StageInput` has no entry-point field, so the container can only omit\n * one if it is a constant of our emitter rather than data. It is: all thirteen\n * `lower*Program` modules write `entryPoint: \"main\"` literally. Measured constant\n * across 626 shaders in seven effects — but measurement only shows it holds\n * today, so the substitution asserts it. A future lowerer that picks a different\n * name fails the build instead of silently emitting a container whose programs\n * cannot be found.\n */\nexport const WGSL_ENTRY_POINT = \"main\";\n\n/**\n * Encodes one WGSL stage program.\n *\n * `sourceMap` is deliberately dropped. Its offsets index DXBC bytes, which this\n * container does not carry, so it is a translator diagnostic rather than\n * payload. It was separately measured to suppress no sharing, so keeping it\n * would buy nothing either.\n *\n * @param {object} shader Translated shader record.\n * @returns {Uint8Array} Program bytes.\n */\nfunction encodeProgram(shader)\n{\n if (shader.entryPoint !== WGSL_ENTRY_POINT)\n {\n throw new Error(\n `WGSL shader ${shader.key} has entry point \"${shader.entryPoint}\"; `\n + `the container omits the name because every lowerer emits \"${WGSL_ENTRY_POINT}\"`\n );\n }\n\n return new TextEncoder().encode(shader.code);\n}\n\n/**\n * Builds the per-pass backend block for one pass of one translated body.\n *\n * @param {object} unit Pass translation unit.\n * @param {string} passKey Enclosing pass key.\n * @returns {Uint8Array|null} Block bytes, or null when the pass has no layout.\n */\nfunction encodeBackendBlock(unit, passKey)\n{\n const layout = unit.layouts.find((entry) => entry.key === passKey);\n if (!layout) return null;\n\n return writeBackendBlock({\n bindGroups: layout.bindGroups,\n transforms: (unit.resourceTransforms ?? [])\n .filter((transform) => transform.layoutKey === passKey)\n });\n}\n\n/** The WebGPU encoders, as the shared builder's backend argument. */\nexport const WGSL_CONTAINER_BACKEND = Object.freeze({ encodeProgram, encodeBackendBlock });\n\n/**\n * Builds the complete WebGPU effect container.\n *\n * @param {object} effectRes Loaded version-15 `Tr2EffectRes`.\n * @param {object} permutationGraph Validated `PGRF` document.\n * @param {object} backendBodySet Translated backend bodies.\n * @param {object} [options] Container options.\n * @param {number[]|Uint8Array} [options.compilerVersion] Four version bytes.\n * @param {string} [options.sourceHash] 32 ASCII hash characters.\n * @returns {{bytes:Uint8Array, permutationCount:number, bodyCount:number}} Container and its body accounting.\n */\nexport function buildCarbonEffectContainer(\n effectRes,\n permutationGraph,\n backendBodySet,\n options = {}\n)\n{\n return buildContainer(\n effectRes,\n permutationGraph,\n backendBodySet,\n WGSL_CONTAINER_BACKEND,\n options\n );\n}\n\nexport default buildCarbonEffectContainer;\n"],"names":["WGSL_ENTRY_POINT","encodeProgram","shader","entryPoint","Error","key","TextEncoder","encode","code","encodeBackendBlock","unit","passKey","layout","layouts","find","entry","writeBackendBlock","bindGroups","transforms","resourceTransforms","filter","transform","layoutKey","WGSL_CONTAINER_BACKEND","Object","freeze","buildCarbonEffectContainer","effectRes","permutationGraph","backendBodySet","options","buildContainer"],"mappings":";;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,gBAAgB,GAAG;;AAEhC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,aAAaA,CAACC,MAAM,EAC7B;AACI,EAAA,IAAIA,MAAM,CAACC,UAAU,KAAKH,gBAAgB,EAC1C;AACI,IAAA,MAAM,IAAII,KAAK,CACX,CAAA,YAAA,EAAeF,MAAM,CAACG,GAAG,CAAA,kBAAA,EAAqBH,MAAM,CAACC,UAAU,CAAA,GAAA,CAAK,GAClE,CAAA,0DAAA,EAA6DH,gBAAgB,GACnF,CAAC;AACL,EAAA;EAEA,OAAO,IAAIM,WAAW,EAAE,CAACC,MAAM,CAACL,MAAM,CAACM,IAAI,CAAC;AAChD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,kBAAkBA,CAACC,IAAI,EAAEC,OAAO,EACzC;AACI,EAAA,MAAMC,MAAM,GAAGF,IAAI,CAACG,OAAO,CAACC,IAAI,CAAEC,KAAK,IAAKA,KAAK,CAACV,GAAG,KAAKM,OAAO,CAAC;AAClE,EAAA,IAAI,CAACC,MAAM,EAAE,OAAO,IAAI;AAExB,EAAA,OAAOI,iBAAiB,CAAC;IACrBC,UAAU,EAAEL,MAAM,CAACK,UAAU;AAC7BC,IAAAA,UAAU,EAAE,CAACR,IAAI,CAACS,kBAAkB,IAAI,EAAE,EACrCC,MAAM,CAAEC,SAAS,IAAKA,SAAS,CAACC,SAAS,KAAKX,OAAO;AAC9D,GAAC,CAAC;AACN;;AAEA;MACaY,sBAAsB,GAAGC,MAAM,CAACC,MAAM,CAAC;EAAExB,aAAa;AAAEQ,EAAAA;AAAmB,CAAC;;AAEzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASiB,0BAA0BA,CACtCC,SAAS,EACTC,gBAAgB,EAChBC,cAAc,EACdC,OAAO,GAAG,EAAE,EAEhB;EACI,OAAOC,4BAAc,CACjBJ,SAAS,EACTC,gBAAgB,EAChBC,cAAc,EACdN,sBAAsB,EACtBO,OACJ,CAAC;AACL;;;;"}
@@ -1,6 +1,6 @@
1
1
  import '../../../../format/compareUtf8.js';
2
2
  import { readBackendBlock } from '../../../../format/carbonEffect/carbonEffectBackendBlock.js';
3
- import { CjsCarbonEffectReader } from '../../../../format/carbonEffect/CjsCarbonEffectReader.js';
3
+ import { looksLikeCarbonEffectContainer, CjsCarbonEffectReader } from '../../../../format/carbonEffect/CjsCarbonEffectReader.js';
4
4
  import '../../../../format/carbonEffect/CjsCarbonEffectWriter.js';
5
5
  import { WGSL_ENTRY_POINT } from '../buildCarbonEffectContainer.js';
6
6
  import { sha256Bytes } from '../../../../format/effect/sha256.js';
@@ -61,9 +61,11 @@ const WEBGPU_STAGE = Object.freeze({
61
61
  * @param {Uint8Array} bytes Candidate bytes.
62
62
  * @returns {boolean} True when the first dword is Carbon's v15 version.
63
63
  */
64
- function looksLikeCewgpuContainer(bytes) {
65
- if (!bytes || bytes.length < 4) return false;
66
- return bytes[0] === 15 && bytes[1] === 0 && bytes[2] === 0 && bytes[3] === 0;
64
+ function looksLikeCarbonWebgpuContainer(bytes) {
65
+ // Delegates rather than repeating the version dword. WebGL needs the same
66
+ // check, and a second hand-written copy of one constant is a second chance
67
+ // to disagree with it.
68
+ return looksLikeCarbonEffectContainer(bytes);
67
69
  }
68
70
 
69
71
  /**
@@ -90,7 +92,7 @@ function optionIndicesFor(axes, permutationIndex) {
90
92
  /**
91
93
  * Reader over one WebGPU effect container.
92
94
  */
93
- class CewgpuContainer {
95
+ class CarbonWebgpuContainer {
94
96
  /**
95
97
  * Creates an empty container reader.
96
98
  */
@@ -121,7 +123,7 @@ class CewgpuContainer {
121
123
  const bytes = source instanceof Uint8Array ? source : source instanceof ArrayBuffer ? new Uint8Array(source) : new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
122
124
  this.bytes = bytes;
123
125
  this.carbon = new CjsCarbonEffectReader(bytes, {
124
- source: this.sourcePath || "CEWGPU"
126
+ source: this.sourcePath || "CARBON_WEBGPU"
125
127
  });
126
128
  this.containerVersion = this.carbon.version;
127
129
  return true;
@@ -152,7 +154,7 @@ class CewgpuContainer {
152
154
  GetDescription(permutationIndex) {
153
155
  const record = this.carbon.records[permutationIndex];
154
156
  if (!record) {
155
- throw new Error(`CEWGPU container has no body at permutation ${permutationIndex}`);
157
+ throw new Error(`Carbon WebGPU container has no body at permutation ${permutationIndex}`);
156
158
  }
157
159
  if (!this._descriptions.has(record.offset)) {
158
160
  this._descriptions.set(record.offset, this.carbon.readDescription(permutationIndex, {
@@ -286,7 +288,7 @@ class CewgpuContainer {
286
288
  if (!shaders.length) continue;
287
289
  const block = pass.backendBlock && pass.backendBlock.size !== 0 ? readBackendBlock(pass.backendBlock.bytes, {
288
290
  layoutKey: passKey,
289
- source: this.sourcePath || "CEWGPU"
291
+ source: this.sourcePath || "CARBON_WEBGPU"
290
292
  }) : null;
291
293
  passes.push(Object.freeze({
292
294
  passKey,
@@ -325,22 +327,6 @@ class CewgpuContainer {
325
327
  return deriveBackendBodySet(this);
326
328
  }
327
329
 
328
- /**
329
- * Returns the Carbon description currently exposed through the legacy
330
- * portable-reflection accessor.
331
- *
332
- * This is not a `CJS_EFFECT_BODY_REFLECTION` envelope. Direct
333
- * `Tr2EffectRes` hydration requires an adapter and remains an open
334
- * integration boundary.
335
- *
336
- * @param {number} [permutationIndex] Permutation index.
337
- * @returns {object|null} Raw Carbon description record tree.
338
- */
339
- GetPortableEffectReflection(permutationIndex = 0) {
340
- if (!this.IsGood()) return null;
341
- return this.GetDescription(permutationIndex);
342
- }
343
-
344
330
  /**
345
331
  * Summarises the container without materialising every body.
346
332
  *
@@ -349,7 +335,7 @@ class CewgpuContainer {
349
335
  get info() {
350
336
  const bodyKeys = this.bodyKeyByOffset;
351
337
  return Object.freeze({
352
- format: "CEWGPU",
338
+ format: "CARBON_WEBGPU",
353
339
  // Carbon's own version dword, always 15. There is no container
354
340
  // version of ours: see buildCarbonEffectContainer for why nothing
355
341
  // announces the payload, and why identity comes from the path.
@@ -364,5 +350,5 @@ class CewgpuContainer {
364
350
  }
365
351
  }
366
352
 
367
- export { CewgpuContainer, looksLikeCewgpuContainer };
368
- //# sourceMappingURL=CewgpuContainer.js.map
353
+ export { CarbonWebgpuContainer, looksLikeCarbonWebgpuContainer };
354
+ //# sourceMappingURL=CarbonWebgpuContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarbonWebgpuContainer.js","sources":["../../../../../../src/formats/webgpu/core/carbonWebgpu/CarbonWebgpuContainer.js"],"sourcesContent":["import {\n CjsCarbonEffectReader,\n readBackendBlock\n} from \"../../../../format/carbonEffect/index.js\";\nimport { WGSL_ENTRY_POINT } from \"../buildCarbonEffectContainer.js\";\nimport { sha256Bytes } from \"../../../../format/effect/sha256.js\";\nimport {\n looksLikeCarbonEffectContainer\n} from \"../../../../format/carbonEffect/CjsCarbonEffectReader.js\";\nimport { deriveBackendBodySet } from \"./containerViews.js\";\n\n/**\n * Reader for the WebGPU effect container.\n *\n * The chunk package stored the permutation graph, the source reflection, the\n * translated body set and the emitted WGSL as four documents that had to be kept\n * consistent with each other, and carried digests to detect when they were not.\n * Under the record layout there is one document. The permutation graph is the\n * header's own permutation records and offset table, the reflection is the\n * description tree, and a translated pass is that tree's `shaderData` plus its\n * trailing block. So the accessors below are **views**, not stored copies, and\n * the class of bug the digests guarded against cannot occur: there is nothing\n * left to disagree.\n *\n * Keys the chunk format stored explicitly are derived here instead:\n *\n * - a body key is its position among distinct offset-table entries, which is\n * exactly what Carbon's alias dedupe produces;\n * - a pass's technique name, pass index and stage name come from its position in\n * the record tree, which is why cross-technique passes share on the wire;\n * - the WGSL entry point is a constant of the emitter, asserted on write.\n */\n\nconst textDecoder = new TextDecoder(\"utf-8\", { fatal: false });\n\n/** WGSL stage names by Carbon stage type, for the stage types WebGPU supports. */\nconst WEBGPU_STAGE_NAME = Object.freeze({ 0: \"vertex\", 1: \"pixel\", 2: \"compute\" });\n\n/** WebGPU pipeline stage for a WGSL stage name. */\nconst WEBGPU_STAGE = Object.freeze({ vertex: \"vertex\", pixel: \"fragment\", compute: \"compute\" });\n\n/**\n * Reports whether bytes look like a Carbon v15 effect container.\n *\n * This is a **shape** check, not an identity check, and the distinction is the\n * point: our containers are stock Carbon v15 files, so nothing in the bytes\n * separates ours from a shipped `effect.dx11` file. Identity comes from where\n * the file was resolved — `effect.webgpu/` versus `effect.dx11/` — exactly as it\n * does for Carbon, whose three backend trees are also byte-format-identical.\n *\n * Use this to reject something that is not a v15 container at all. Do not use it\n * to decide what a payload is.\n *\n * @param {Uint8Array} bytes Candidate bytes.\n * @returns {boolean} True when the first dword is Carbon's v15 version.\n */\nexport function looksLikeCarbonWebgpuContainer(bytes)\n{\n // Delegates rather than repeating the version dword. WebGL needs the same\n // check, and a second hand-written copy of one constant is a second chance\n // to disagree with it.\n return looksLikeCarbonEffectContainer(bytes);\n}\n\n/**\n * Decomposes a permutation index into per-axis option indices.\n *\n * The inverse of Carbon's own selection arithmetic: it accumulates\n * `value * multiplier` over the axes in declaration order, multiplying the\n * running radix by each axis's option count.\n *\n * @param {object[]} axes Permutation axis records.\n * @param {number} permutationIndex Permutation index.\n * @returns {number[]} Option index per axis.\n */\nfunction optionIndicesFor(axes, permutationIndex)\n{\n let remaining = permutationIndex;\n return axes.map((axis) =>\n {\n const radix = axis.options.length || 1;\n const value = remaining % radix;\n remaining = Math.floor(remaining / radix);\n return value;\n });\n}\n\n/**\n * Reader over one WebGPU effect container.\n */\nexport class CarbonWebgpuContainer\n{\n /**\n * Creates an empty container reader.\n */\n constructor()\n {\n this.readError = null;\n this.sourcePath = \"\";\n this.containerVersion = 0;\n this.bytes = null;\n this.carbon = null;\n this._descriptions = new Map();\n this._bodyKeyByOffset = null;\n }\n\n /**\n * Reads a container from bytes.\n *\n * @param {ArrayBuffer|ArrayBufferView|Uint8Array} source Container bytes.\n * @param {object} [options] Read options.\n * @param {string} [options.sourcePath] Source path for diagnostics.\n * @returns {boolean} True when the container was decoded.\n */\n Read(source, options = {})\n {\n this.readError = null;\n this.sourcePath = options.sourcePath || \"\";\n this._descriptions = new Map();\n this._bodyKeyByOffset = null;\n\n try\n {\n const bytes = source instanceof Uint8Array\n ? source\n : (source instanceof ArrayBuffer\n ? new Uint8Array(source)\n : new Uint8Array(source.buffer, source.byteOffset, source.byteLength));\n\n this.bytes = bytes;\n this.carbon = new CjsCarbonEffectReader(bytes, {\n source: this.sourcePath || \"CARBON_WEBGPU\"\n });\n this.containerVersion = this.carbon.version;\n return true;\n }\n catch (error)\n {\n this.readError = error;\n this.carbon = null;\n return false;\n }\n }\n\n /**\n * Reports whether the container decoded.\n *\n * @returns {boolean} True when readable.\n */\n IsGood()\n {\n return this.carbon !== null;\n }\n\n /**\n * Reads one permutation's description, memoised by stored body.\n *\n * Aliased permutations share one stored blob, so they share one parse.\n *\n * @param {number} permutationIndex Permutation index.\n * @returns {object} Description record tree.\n */\n GetDescription(permutationIndex)\n {\n const record = this.carbon.records[permutationIndex];\n if (!record)\n {\n throw new Error(`Carbon WebGPU container has no body at permutation ${permutationIndex}`);\n }\n if (!this._descriptions.has(record.offset))\n {\n this._descriptions.set(\n record.offset,\n this.carbon.readDescription(permutationIndex, { backend: true })\n );\n }\n return this._descriptions.get(record.offset);\n }\n\n /**\n * Maps each distinct stored body to a stable key, in offset-table order.\n *\n * @returns {Map<number, string>} Body key by stored offset.\n */\n get bodyKeyByOffset()\n {\n if (!this._bodyKeyByOffset)\n {\n const keys = new Map();\n for (const record of this.carbon.records)\n {\n if (!keys.has(record.offset)) keys.set(record.offset, `body${keys.size}`);\n }\n this._bodyKeyByOffset = keys;\n }\n return this._bodyKeyByOffset;\n }\n\n /**\n * Derives the permutation graph the chunk package used to store.\n *\n * @returns {object} Permutation graph view.\n */\n get permutationGraph()\n {\n const bodyKeys = this.bodyKeyByOffset;\n const bodies = [];\n\n for (const [ offset, key ] of bodyKeys)\n {\n const record = this.carbon.records.find((entry) => entry.offset === offset);\n bodies.push(Object.freeze({\n key,\n offset,\n byteLength: record.size,\n // Hashed from the stored description blob. The chunk graph\n // carried a digest per body; here it is a function of the bytes\n // it identifies, so it cannot disagree with them. It is also what\n // Tr2EffectRes uses to prove bodies are distinct -- aliased rows\n // share one blob and therefore one digest, which is exactly the\n // identity the offset table already expresses.\n sha256: sha256Bytes(this.bytes.subarray(offset, offset + record.size)),\n permutationCount: this.carbon.records\n .filter((entry) => entry.offset === offset).length\n }));\n }\n\n return Object.freeze({\n // The envelope the chunk `PGRF` document carried. Not provenance:\n // `Tr2EffectRes.SetPayload` validates it before accepting a payload\n // at all, so a graph without it is refused outright.\n format: \"CJS_EFFECT_PERMUTATION_GRAPH\",\n formatVersion: 1,\n // Fixed by construction rather than recorded. A container always\n // carries every permutation, the offset table gives body identity\n // only, and source reflection is not a separate document.\n coverage: Object.freeze({\n permutations: \"complete\",\n bodies: \"identity-only\",\n reflection: \"absent\"\n }),\n axes: Object.freeze(this.carbon.permutations.map((axis, index) => Object.freeze({\n index,\n name: axis.name.value,\n defaultOption: axis.defaultOption,\n description: axis.description.value,\n type: axis.type,\n options: Object.freeze(axis.options.map((option) => option.value))\n }))),\n variants: Object.freeze(this.carbon.records.map((record, permutationIndex) =>\n Object.freeze({\n permutationIndex,\n bodyKey: bodyKeys.get(record.offset),\n // Mixed-radix decomposition of the index over the axes, which\n // is the inverse of the sum Carbon's GetShader() builds when\n // it walks options in declaration order.\n optionIndices: Object.freeze(\n optionIndicesFor(this.carbon.permutations, permutationIndex)\n ),\n // The offset-table row itself. Aliased permutations share a\n // stored record, so the consumer can prove that two\n // permutations resolve to the same emitted bytes.\n sourceRecord: Object.freeze({\n offset: record.offset,\n byteLength: record.size\n })\n }))),\n bodies: Object.freeze(bodies)\n });\n }\n\n /**\n * Resolves the translated backend passes for one permutation.\n *\n * A body whose stages carry no program is reported unsupported, which is\n * what a zero-length `shaderData` means: the reflection is known, the\n * program is not.\n *\n * @param {number} [permutationIndex] Permutation index.\n * @returns {object|null} Resolved backend body.\n */\n GetBackendBodyPrograms(permutationIndex = 0)\n {\n if (!this.IsGood()) return null;\n\n const record = this.carbon.records[permutationIndex];\n if (!record) return null;\n\n const description = this.GetDescription(permutationIndex);\n const bodyKey = this.bodyKeyByOffset.get(record.offset);\n const passes = [];\n let translated = false;\n\n for (const technique of description.techniques)\n {\n for (const [ passIndex, pass ] of technique.passes.entries())\n {\n const passKey = `${technique.name.value}.pass${passIndex}`;\n const shaders = [];\n\n for (const stage of pass.stages)\n {\n const stageName = WEBGPU_STAGE_NAME[stage.type];\n if (!stageName || stage.shaderData.size === 0) continue;\n translated = true;\n shaders.push(Object.freeze({\n key: `${passKey}.${stageName}`,\n techniqueName: technique.name.value,\n passIndex,\n stageName,\n stage: WEBGPU_STAGE[stageName],\n stageType: stage.type,\n entryPoint: WGSL_ENTRY_POINT,\n code: textDecoder.decode(stage.shaderData.bytes),\n ...(stageName === \"compute\"\n ? { threadGroupSize: [ ...stage.threadGroupSize ] }\n : {})\n }));\n }\n\n if (!shaders.length) continue;\n\n const block = pass.backendBlock && pass.backendBlock.size !== 0\n ? readBackendBlock(pass.backendBlock.bytes, {\n layoutKey: passKey,\n source: this.sourcePath || \"CARBON_WEBGPU\"\n })\n : null;\n\n passes.push(Object.freeze({\n passKey,\n shaders: Object.freeze(shaders),\n layouts: Object.freeze(block\n ? [ Object.freeze({\n key: passKey,\n techniqueName: technique.name.value,\n passIndex,\n bindGroups: block.bindGroups\n }) ]\n : []),\n ...(block?.transforms?.length\n ? { resourceTransforms: Object.freeze(block.transforms) }\n : {})\n }));\n }\n }\n\n return Object.freeze({\n permutationIndex,\n bodyKey,\n status: translated ? \"translated\" : \"unsupported\",\n error: translated ? null : \"body carries no translated programs\",\n passes: Object.freeze(passes)\n });\n }\n\n /**\n * Derives the body-set view, for consumers holding the raw container.\n *\n * `packageToJson` exposes the same document. A consumer taking the raw emit\n * reads it here instead, which is why this is a getter on the container\n * rather than only a field in the JSON projection.\n *\n * @returns {object} Body-set document.\n */\n get backendBodySet()\n {\n return deriveBackendBodySet(this);\n }\n\n /**\n * Summarises the container without materialising every body.\n *\n * @returns {object} Container summary.\n */\n get info()\n {\n const bodyKeys = this.bodyKeyByOffset;\n return Object.freeze({\n format: \"CARBON_WEBGPU\",\n // Carbon's own version dword, always 15. There is no container\n // version of ours: see buildCarbonEffectContainer for why nothing\n // announces the payload, and why identity comes from the path.\n containerVersion: this.containerVersion,\n sourcePath: this.sourcePath,\n compilerVersion: Object.freeze([ ...this.carbon.compilerVersion ]),\n sourceHash: textDecoder.decode(this.carbon.sourceHash),\n permutationCount: this.carbon.records.length,\n uniqueBodyCount: bodyKeys.size,\n axisCount: this.carbon.permutations.length\n });\n }\n}\n\nexport default CarbonWebgpuContainer;\n"],"names":["textDecoder","TextDecoder","fatal","WEBGPU_STAGE_NAME","Object","freeze","WEBGPU_STAGE","vertex","pixel","compute","looksLikeCarbonWebgpuContainer","bytes","looksLikeCarbonEffectContainer","optionIndicesFor","axes","permutationIndex","remaining","map","axis","radix","options","length","value","Math","floor","CarbonWebgpuContainer","constructor","readError","sourcePath","containerVersion","carbon","_descriptions","Map","_bodyKeyByOffset","Read","source","Uint8Array","ArrayBuffer","buffer","byteOffset","byteLength","CjsCarbonEffectReader","version","error","IsGood","GetDescription","record","records","Error","has","offset","set","readDescription","backend","get","bodyKeyByOffset","keys","size","permutationGraph","bodyKeys","bodies","key","find","entry","push","sha256","sha256Bytes","subarray","permutationCount","filter","format","formatVersion","coverage","permutations","reflection","index","name","defaultOption","description","type","option","variants","bodyKey","optionIndices","sourceRecord","GetBackendBodyPrograms","passes","translated","technique","techniques","passIndex","pass","entries","passKey","shaders","stage","stages","stageName","shaderData","techniqueName","stageType","entryPoint","WGSL_ENTRY_POINT","code","decode","threadGroupSize","block","backendBlock","readBackendBlock","layoutKey","layouts","bindGroups","transforms","resourceTransforms","status","backendBodySet","deriveBackendBodySet","info","compilerVersion","sourceHash","uniqueBodyCount","axisCount"],"mappings":"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"}
@@ -341,7 +341,7 @@ function deriveInfo(container, options = {}) {
341
341
  const source = options.source || container.sourcePath || "memory";
342
342
  const graph = container.permutationGraph;
343
343
  return {
344
- format: "CEWGPU",
344
+ format: "CARBON_WEBGPU",
345
345
  packageKind: "tr2-effect-webgpu",
346
346
  sourcePath: source,
347
347
  effectVersion: container.carbon.version,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"containerViews.js","sources":["../../../../../../src/formats/webgpu/core/carbonWebgpu/containerViews.js"],"sourcesContent":["import { HlslEffectBindingManifest } from \"../../../hlsl/core/tr2/shader/HlslEffectBindingManifest.js\";\nimport { HlslShaderBytecode } from \"../../../hlsl/core/HlslShaderBytecode.js\";\nimport { hlslShaderStageName } from \"../../../hlsl/core/tr2/HlslRenderContextEnum.js\";\nimport { runtimeDescriptionFromCarbon } from \"../../../hlsl/core/carbonDescriptionToRuntime.js\";\nimport { buildEffectAnalysis } from \"../helpers.js\";\nimport { WGSL_SET_VERSION } from \"../wgsl/buildWgslSet.js\";\nimport { sha256Utf8 } from \"../../../../format/effect/sha256.js\";\n\n/**\n * Derived compatibility views over a container.\n *\n * The chunk package stored `ANLS` and `WGSL` as documents beside the reflection\n * they were computed from, and carried digests to detect the two disagreeing.\n * The container stores one document, so these are **views**: functions of the\n * records, computed on read. The class of bug the digests guarded cannot occur,\n * because there is no second copy to drift.\n *\n * The analysis view is deliberately not a reimplementation. It runs\n * `buildEffectAnalysis` — the same function the packager runs on source — over a\n * description rebuilt by `runtimeDescriptionFromCarbon`. That is what keeps the\n * view honest: if it were rewritten to emit the fields consumers read today, it\n * would be free to drift from the real analysis, and nothing would notice.\n * `carbon-analysis-adapter-corpus.test.mjs` diffs the two over every shipped\n * permutation and finds zero differences.\n *\n * These views exist for `engine-webgpu`, which reads format-package JSON for\n * Carbon reflection instead of reading `Tr2Shader`. That is a recorded layering\n * defect and is not this port's to fix; the views keep it working unchanged\n * while the wire format moves underneath it. They go away with that cleanup.\n */\n\n/**\n * Resolves the permutation Carbon's own `GetShader()` would select with no\n * option overrides.\n *\n * Carbon multiplies each axis's default option by the running product of the\n * preceding axes' option counts. The chunk package stored a single selected\n * body and its index; the container carries every permutation, so the view has\n * to name a default rather than inherit one, and Carbon's own default is the\n * only defensible choice.\n *\n * @param {object} container Loaded container.\n * @returns {number} Permutation index.\n */\nexport function defaultPermutationIndex(container)\n{\n let multiplier = 1;\n let index = 0;\n for (const axis of container.carbon.permutations)\n {\n index += axis.defaultOption * multiplier;\n multiplier *= axis.options.length || 1;\n }\n return index < container.carbon.records.length ? index : 0;\n}\n\n/**\n * Rebuilds the runtime effect description for one permutation.\n *\n * @param {object} container Loaded container.\n * @param {number} permutationIndex Permutation index.\n * @param {string} source Source label.\n * @returns {object} Runtime-shaped effect description.\n */\nfunction describeRuntime(container, permutationIndex, source)\n{\n return runtimeDescriptionFromCarbon(container.GetDescription(permutationIndex), {\n effectName: source,\n version: container.carbon.version,\n bytecodeFor: (stage, stageType) => new HlslShaderBytecode({\n stageType,\n // Carbon's six stage names, not WebGPU's three. A three-entry table\n // reports a geometry stage as null, which the corpus caught.\n stageName: hlslShaderStageName(stageType),\n bytes: stage.shaderData.bytes,\n shaderSize: stage.shaderData.size,\n stringTableOffset: stage.shaderData.offset,\n effectName: source\n })\n });\n}\n\n/**\n * Derives the analysis document for one permutation.\n *\n * One field is honestly different from the stored `ANLS` it replaces:\n * `stages[].shaderBytecode` describes the **WGSL** program the container\n * carries, where the stored document described the source DXBC. The container\n * does not carry DXBC, so reproducing the old numbers would mean inventing\n * them. Nothing in the engine's read surface uses this field; it is a\n * diagnostic.\n *\n * @param {object} container Loaded container.\n * @param {object} [options] View options.\n * @param {string} [options.source] Source label.\n * @param {number} [options.permutationIndex] Permutation to describe.\n * @returns {object} Analysis document.\n */\nexport function deriveAnalysis(container, options = {})\n{\n const source = options.source || container.sourcePath || \"memory\";\n const permutationIndex = options.permutationIndex ?? defaultPermutationIndex(container);\n const effectDescription = describeRuntime(container, permutationIndex, source);\n\n return buildEffectAnalysis({\n effectDescription,\n bindingManifest: HlslEffectBindingManifest.fromEffectDescription(effectDescription, {\n effectName: source\n }),\n effectRes: {\n sourcePath: source,\n m_compilerVersion: null\n },\n selection: {\n bodyIndex: permutationIndex,\n selectedOptions: container.carbon.permutations.map((axis) => ({\n name: axis.name.value,\n value: axis.options[axis.defaultOption]?.value ?? null\n }))\n }\n }, { source, decodeBytecode: false, decodeInstructions: false });\n}\n\n/**\n * Derives the WGSL set document for one permutation.\n *\n * `sourceMap` is absent rather than empty, and that is not an oversight: its\n * offsets index DXBC bytes the container does not carry, so it is a translator\n * diagnostic and was dropped on write. It was separately measured to suppress\n * no sharing, so keeping it would have bought nothing either.\n *\n * @param {object} container Loaded container.\n * @param {object} [options] View options.\n * @param {number} [options.permutationIndex] Permutation to describe.\n * @returns {object} WGSL set document.\n */\nexport function deriveWgsl(container, options = {})\n{\n const permutationIndex = options.permutationIndex ?? defaultPermutationIndex(container);\n const body = container.GetBackendBodyPrograms(permutationIndex);\n const shaders = [];\n const layouts = [];\n const resourceTransforms = [];\n\n for (const pass of body?.passes ?? [])\n {\n for (const shader of pass.shaders)\n {\n shaders.push({\n key: shader.key,\n techniqueName: shader.techniqueName,\n passIndex: shader.passIndex,\n stageName: shader.stageName,\n stage: shader.stage,\n stageType: shader.stageType,\n entryPoint: shader.entryPoint,\n code: shader.code,\n ...(shader.threadGroupSize ? { threadGroupSize: [ ...shader.threadGroupSize ] } : {})\n });\n }\n for (const layout of pass.layouts) layouts.push(layout);\n for (const transform of pass.resourceTransforms ?? []) resourceTransforms.push(transform);\n }\n\n return {\n format: \"CJS_WGSL_SET\",\n formatVersion: WGSL_SET_VERSION,\n shaders,\n layouts,\n ...(resourceTransforms.length ? { resourceTransforms } : {})\n };\n}\n\n/**\n * Derives the `WGSB` body-set view the chunk package used to store.\n *\n * `engine-webgpu` resolves a permutation's translated programs through this,\n * which is part of the recorded layering defect -- it should read the shader,\n * not a package document. The view keeps that path working unchanged while the\n * wire format moves underneath it, and goes away with the cleanup.\n *\n * Nothing here is stored. A body's status is whether its stages carry programs,\n * its passes are the record tree's passes, and a pass unit is that pass's\n * shaders and layouts. Bodies are keyed by distinct stored offset, which is\n * exactly what Carbon's alias dedupe produces.\n *\n * @param {object} container Loaded container.\n * @returns {object} Body-set document.\n */\nexport function deriveBackendBodySet(container)\n{\n const bodyKeys = container.bodyKeyByOffset;\n const passUnits = [];\n const bodies = [];\n const seen = new Set();\n\n for (let index = 0; index < container.carbon.records.length; index += 1)\n {\n const offset = container.carbon.records[index].offset;\n if (seen.has(offset)) continue;\n seen.add(offset);\n\n const bodyKey = bodyKeys.get(offset);\n const body = container.GetBackendBodyPrograms(index);\n\n if (!body || body.status !== \"translated\")\n {\n bodies.push({\n bodyKey,\n representativePermutationIndex: index,\n status: \"unsupported\",\n error: body?.error ?? \"body carries no translated programs\",\n passCount: 0,\n passes: []\n });\n continue;\n }\n\n const passes = [];\n for (const pass of body.passes)\n {\n const unit = {\n key: `unit${passUnits.length}`,\n // Hashed from the unit's own content. The chunk body set stored\n // this digest to detect a unit drifting from what referenced it;\n // derived from the content it identifies, it cannot.\n sha256: sha256Utf8(`${JSON.stringify({\n shaders: pass.shaders,\n layouts: pass.layouts,\n resourceTransforms: pass.resourceTransforms ?? []\n })}\n`),\n wgslSetVersion: WGSL_SET_VERSION,\n shaders: pass.shaders,\n layouts: pass.layouts,\n ...(pass.resourceTransforms?.length\n ? { resourceTransforms: pass.resourceTransforms }\n : {})\n };\n passUnits.push(unit);\n passes.push({ passKey: pass.passKey, unitKey: unit.key });\n }\n\n bodies.push({\n bodyKey,\n representativePermutationIndex: index,\n status: \"translated\",\n error: null,\n passCount: passes.length,\n passes\n });\n }\n\n return {\n format: \"CJS_WGSL_BODY_SET\",\n formatVersion: 1,\n bodyCount: bodies.length,\n translatedBodyCount: bodies.filter((body) => body.status === \"translated\").length,\n passUnitCount: passUnits.length,\n passUnits,\n bodies\n };\n}\n\n/**\n * Finds the permutation a package resolves to.\n *\n * A \"selected\" package is not a different format -- the container always carries\n * every permutation. What makes it selected is that exactly one body was\n * translated, so the resolved permutation is the first one whose body carries\n * programs. When every body is translated, there is nothing to single out and\n * Carbon's own default applies.\n *\n * @param {object} container Loaded container.\n * @returns {number} Permutation index.\n */\nexport function resolvedPermutationIndex(container)\n{\n const translated = [];\n const seen = new Set();\n\n for (let index = 0; index < container.carbon.records.length; index += 1)\n {\n const offset = container.carbon.records[index].offset;\n if (seen.has(offset)) continue;\n seen.add(offset);\n\n const body = container.GetBackendBodyPrograms(index);\n if (body?.status === \"translated\") translated.push(index);\n if (translated.length > 1) return defaultPermutationIndex(container);\n }\n\n return translated.length === 1 ? translated[0] : defaultPermutationIndex(container);\n}\n\n/**\n * Derives the `META`-shaped view the chunk package used to store.\n *\n * Every field here is recovered from the records rather than carried:\n * `selectedOptions` from the resolved permutation's option indices, and\n * `wgslSelection` from which passes and stages actually hold programs. Build-time\n * *policy* -- `bodyMode`, `sourceIdentity`, `completeness` -- is deliberately not\n * here: it describes how the artifact was produced, not what it is, and Carbon\n * stores none of it.\n *\n * @param {object} container Loaded container.\n * @param {object} [options] View options.\n * @param {string} [options.source] Source label.\n * @param {number} [options.permutationIndex] Permutation to describe.\n * @returns {object} Metadata document.\n */\nexport function deriveMetadata(container, options = {})\n{\n const source = options.source || container.sourcePath || \"memory\";\n const permutationIndex = options.permutationIndex ?? resolvedPermutationIndex(container);\n const variant = container.permutationGraph.variants[permutationIndex];\n const axes = container.carbon.permutations;\n\n const selectedOptions = axes.map((axis, axisIndex) => ({\n name: axis.name.value,\n value: axis.options[variant?.optionIndices?.[axisIndex] ?? axis.defaultOption]?.value ?? null\n }));\n\n const body = container.GetBackendBodyPrograms(permutationIndex);\n const selectedStageKeys = (body?.passes ?? [])\n .flatMap((pass) => pass.shaders.map((shader) => shader.key));\n const passKeys = (body?.passes ?? []).map((pass) => pass.passKey);\n\n return {\n effectName: source,\n sourcePath: source,\n bodyIndex: permutationIndex,\n selectedOptions,\n ...(passKeys.length === 1\n ? {\n wgslSelection: {\n mode: \"explicit\",\n completePasses: true,\n techniqueName: passKeys[0].slice(0, passKeys[0].lastIndexOf(\".pass\")),\n passIndex: Number(/\\.pass([0-9]+)$/u.exec(passKeys[0])?.[1] ?? 0),\n requestedStageNames: Array.from(new Set(\n (body?.passes ?? []).flatMap((pass) => pass.shaders.map((shader) => shader.stageName))\n )),\n selectedStageKeys\n }\n }\n : {})\n };\n}\n\n/**\n * Derives the `INFO`-shaped summary the chunk package used to store.\n *\n * Everything here is counted from the records rather than trusted from a stored\n * field, which is why no digest accompanies it: a count derived from the thing\n * it counts cannot disagree with it.\n *\n * @param {object} container Loaded container.\n * @param {object} [options] View options.\n * @param {string} [options.source] Source label.\n * @returns {object} Info document.\n */\nexport function deriveInfo(container, options = {})\n{\n const source = options.source || container.sourcePath || \"memory\";\n const graph = container.permutationGraph;\n return {\n format: \"CARBON_WEBGPU\",\n packageKind: \"tr2-effect-webgpu\",\n sourcePath: source,\n effectVersion: container.carbon.version,\n compilerVersion: [ ...container.carbon.compilerVersion ],\n permutationCount: graph.variants.length,\n uniqueBodyCount: graph.bodies.length\n };\n}\n\nexport default deriveAnalysis;\n"],"names":["defaultPermutationIndex","container","multiplier","index","axis","carbon","permutations","defaultOption","options","length","records","describeRuntime","permutationIndex","source","runtimeDescriptionFromCarbon","GetDescription","effectName","version","bytecodeFor","stage","stageType","HlslShaderBytecode","stageName","hlslShaderStageName","bytes","shaderData","shaderSize","size","stringTableOffset","offset","deriveAnalysis","sourcePath","effectDescription","buildEffectAnalysis","bindingManifest","HlslEffectBindingManifest","fromEffectDescription","effectRes","m_compilerVersion","selection","bodyIndex","selectedOptions","map","name","value","decodeBytecode","decodeInstructions","deriveWgsl","body","GetBackendBodyPrograms","shaders","layouts","resourceTransforms","pass","passes","shader","push","key","techniqueName","passIndex","entryPoint","code","threadGroupSize","layout","transform","format","formatVersion","WGSL_SET_VERSION","deriveBackendBodySet","bodyKeys","bodyKeyByOffset","passUnits","bodies","seen","Set","has","add","bodyKey","get","status","representativePermutationIndex","error","passCount","unit","sha256","sha256Utf8","JSON","stringify","wgslSetVersion","passKey","unitKey","bodyCount","translatedBodyCount","filter","passUnitCount","resolvedPermutationIndex","translated","deriveMetadata","variant","permutationGraph","variants","axes","axisIndex","optionIndices","selectedStageKeys","flatMap","passKeys","wgslSelection","mode","completePasses","slice","lastIndexOf","Number","exec","requestedStageNames","Array","from","deriveInfo","graph","packageKind","effectVersion","compilerVersion","permutationCount","uniqueBodyCount"],"mappings":"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"}
@@ -35,7 +35,7 @@ const WEBGPU_STAGE_TYPES = new Set([0, 1, 2]);
35
35
  /**
36
36
  * Validates a loaded container for WebGPU consumption.
37
37
  *
38
- * @param {object} container Loaded `CewgpuContainer`.
38
+ * @param {object} container Loaded `CarbonWebgpuContainer`.
39
39
  * @param {object} [options] Validation options.
40
40
  * @param {string} [options.source] Source label for diagnostics.
41
41
  * @throws {WebgpuReadError} When the container cannot serve WebGPU.
@@ -43,13 +43,13 @@ const WEBGPU_STAGE_TYPES = new Set([0, 1, 2]);
43
43
  function validateEffectContainer(container, options = {}) {
44
44
  const source = options.source || container.sourcePath || "memory";
45
45
  if (!container?.IsGood()) {
46
- throw new WebgpuReadError("CEWGPU container is not readable", {
46
+ throw new WebgpuReadError("Carbon WebGPU container is not readable", {
47
47
  source,
48
48
  cause: container?.readError ?? null
49
49
  });
50
50
  }
51
51
  if (!container.carbon.records.length) {
52
- throw new WebgpuReadError("CEWGPU container declares no permutation bodies", {
52
+ throw new WebgpuReadError("Carbon WebGPU container declares no permutation bodies", {
53
53
  source
54
54
  });
55
55
  }
@@ -73,7 +73,7 @@ function validateEffectContainer(container, options = {}) {
73
73
  // is about stages with a program, not about stages.
74
74
  if (stage.shaderData.size === 0) continue;
75
75
  if (!WEBGPU_STAGE_TYPES.has(stage.type)) {
76
- throw new WebgpuReadError(`CEWGPU container carries a program for stage type ${stage.type}, ` + "which WebGPU cannot express", {
76
+ throw new WebgpuReadError(`Carbon WebGPU container carries a program for stage type ${stage.type}, ` + "which WebGPU cannot express", {
77
77
  source,
78
78
  permutationIndex: index,
79
79
  pass: `${technique.name.value}.pass${passIndex}`,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateContainer.js","sources":["../../../../../../src/formats/webgpu/core/carbonWebgpu/validateContainer.js"],"sourcesContent":["import { WebgpuReadError } from \"../errors.js\";\n\n/**\n * Structural validation for a loaded WebGPU effect container.\n *\n * This replaces `validateEffectPackageEnvelope`, which was 1762 lines. Most of\n * that is **deleted rather than translated**, and the reason matters: those\n * checks were not format invariants. The chunk container shattered one logical\n * tree into flat string-keyed arrays across `INFO`, `META`, `ANLS`, `WGSL`,\n * `PGRF` and `WGSB`, each holding a projection of the same effect, and roughly\n * 600 lines asserted that the projections still agreed with each other. A record\n * layout makes that question unaskable: containment replaces reference, position\n * replaces key, and the count word before an array replaces `Array.isArray`.\n *\n * What is deliberately **not** re-checked here, because phase 1 already enforces\n * it and checking twice means two places to keep correct:\n *\n * - count caps, arena containment, offset-table density and positional indexing,\n * and the version range — `CjsCarbonEffectReader`;\n * - every sized record parsing to exactly its declared end — Rule 1, in the\n * record codec and the block codec;\n * - duplicate stage type within a pass, and stage-type range — the shape adapter\n * fails closed on both, which is where a runtime description is built.\n *\n * What remains is the one thing that is genuinely this layer's: the container\n * admits all six of Carbon's stage types by design, and WebGPU can express three.\n * That restriction belongs to the backend, not to the container — the Carbon\n * region is backend-invariant, and a container that admitted only three would not\n * be Carbon's container.\n */\n\n/** Stage types WebGPU can express, by Carbon's `InputStageType` numbering. */\nconst WEBGPU_STAGE_TYPES = new Set([ 0, 1, 2 ]);\n\n/**\n * Validates a loaded container for WebGPU consumption.\n *\n * @param {object} container Loaded `CarbonWebgpuContainer`.\n * @param {object} [options] Validation options.\n * @param {string} [options.source] Source label for diagnostics.\n * @throws {WebgpuReadError} When the container cannot serve WebGPU.\n */\nexport function validateEffectContainer(container, options = {})\n{\n const source = options.source || container.sourcePath || \"memory\";\n\n if (!container?.IsGood())\n {\n throw new WebgpuReadError(\"Carbon WebGPU container is not readable\", {\n source,\n cause: container?.readError ?? null\n });\n }\n\n if (!container.carbon.records.length)\n {\n throw new WebgpuReadError(\"Carbon WebGPU container declares no permutation bodies\", { source });\n }\n\n // One check per distinct stored body. Aliased rows share a blob, so checking\n // per permutation would re-check identical bytes up to twenty times over on\n // the effects that alias hardest.\n const checked = new Set();\n\n for (let index = 0; index < container.carbon.records.length; index += 1)\n {\n const offset = container.carbon.records[index].offset;\n if (checked.has(offset)) continue;\n checked.add(offset);\n\n const description = container.GetDescription(index);\n\n for (const technique of description.techniques)\n {\n for (const [ passIndex, pass ] of technique.passes.entries())\n {\n for (const stage of pass.stages)\n {\n // A stage carrying no program is reflection-only: the body\n // is known, the translation is not, and the emitter says so\n // with a zero-length payload. Those are legitimate — 107\n // shipped body-passes carry a geometry stage — so the rule\n // is about stages with a program, not about stages.\n if (stage.shaderData.size === 0) continue;\n\n if (!WEBGPU_STAGE_TYPES.has(stage.type))\n {\n throw new WebgpuReadError(\n `Carbon WebGPU container carries a program for stage type ${stage.type}, `\n + \"which WebGPU cannot express\",\n {\n source,\n permutationIndex: index,\n pass: `${technique.name.value}.pass${passIndex}`,\n stageType: stage.type\n }\n );\n }\n }\n }\n }\n }\n}\n\nexport default validateEffectContainer;\n"],"names":["WEBGPU_STAGE_TYPES","Set","validateEffectContainer","container","options","source","sourcePath","IsGood","WebgpuReadError","cause","readError","carbon","records","length","checked","index","offset","has","add","description","GetDescription","technique","techniques","passIndex","pass","passes","entries","stage","stages","shaderData","size","type","permutationIndex","name","value","stageType"],"mappings":";;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAMA,kBAAkB,GAAG,IAAIC,GAAG,CAAC,CAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAE,CAAC;;AAE/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,uBAAuBA,CAACC,SAAS,EAAEC,OAAO,GAAG,EAAE,EAC/D;EACI,MAAMC,MAAM,GAAGD,OAAO,CAACC,MAAM,IAAIF,SAAS,CAACG,UAAU,IAAI,QAAQ;AAEjE,EAAA,IAAI,CAACH,SAAS,EAAEI,MAAM,EAAE,EACxB;AACI,IAAA,MAAM,IAAIC,eAAe,CAAC,yCAAyC,EAAE;MACjEH,MAAM;AACNI,MAAAA,KAAK,EAAEN,SAAS,EAAEO,SAAS,IAAI;AACnC,KAAC,CAAC;AACN,EAAA;EAEA,IAAI,CAACP,SAAS,CAACQ,MAAM,CAACC,OAAO,CAACC,MAAM,EACpC;AACI,IAAA,MAAM,IAAIL,eAAe,CAAC,wDAAwD,EAAE;AAAEH,MAAAA;AAAO,KAAC,CAAC;AACnG,EAAA;;AAEA;AACA;AACA;AACA,EAAA,MAAMS,OAAO,GAAG,IAAIb,GAAG,EAAE;AAEzB,EAAA,KAAK,IAAIc,KAAK,GAAG,CAAC,EAAEA,KAAK,GAAGZ,SAAS,CAACQ,MAAM,CAACC,OAAO,CAACC,MAAM,EAAEE,KAAK,IAAI,CAAC,EACvE;IACI,MAAMC,MAAM,GAAGb,SAAS,CAACQ,MAAM,CAACC,OAAO,CAACG,KAAK,CAAC,CAACC,MAAM;AACrD,IAAA,IAAIF,OAAO,CAACG,GAAG,CAACD,MAAM,CAAC,EAAE;AACzBF,IAAAA,OAAO,CAACI,GAAG,CAACF,MAAM,CAAC;AAEnB,IAAA,MAAMG,WAAW,GAAGhB,SAAS,CAACiB,cAAc,CAACL,KAAK,CAAC;AAEnD,IAAA,KAAK,MAAMM,SAAS,IAAIF,WAAW,CAACG,UAAU,EAC9C;AACI,MAAA,KAAK,MAAM,CAAEC,SAAS,EAAEC,IAAI,CAAE,IAAIH,SAAS,CAACI,MAAM,CAACC,OAAO,EAAE,EAC5D;AACI,QAAA,KAAK,MAAMC,KAAK,IAAIH,IAAI,CAACI,MAAM,EAC/B;AACI;AACA;AACA;AACA;AACA;AACA,UAAA,IAAID,KAAK,CAACE,UAAU,CAACC,IAAI,KAAK,CAAC,EAAE;UAEjC,IAAI,CAAC9B,kBAAkB,CAACiB,GAAG,CAACU,KAAK,CAACI,IAAI,CAAC,EACvC;YACI,MAAM,IAAIvB,eAAe,CACrB,CAAA,yDAAA,EAA4DmB,KAAK,CAACI,IAAI,CAAA,EAAA,CAAI,GACxE,6BAA6B,EAC/B;cACI1B,MAAM;AACN2B,cAAAA,gBAAgB,EAAEjB,KAAK;cACvBS,IAAI,EAAE,GAAGH,SAAS,CAACY,IAAI,CAACC,KAAK,CAAA,KAAA,EAAQX,SAAS,CAAA,CAAE;cAChDY,SAAS,EAAER,KAAK,CAACI;AACrB,aACJ,CAAC;AACL,UAAA;AACJ,QAAA;AACJ,MAAA;AACJ,IAAA;AACJ,EAAA;AACJ;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { HlslEffectBindingManifest } from '../../hlsl/core/tr2/shader/HlslEffectBindingManifest.js';
2
- import { enumerateUniqueEffectBodies } from '../../hlsl/core/portableReflection.js';
2
+ import { enumerateUniqueEffectBodies } from '../../../format/effect/effectBodyInventory.js';
3
3
  import { buildEffectAnalysis } from './helpers.js';
4
4
  import { normalizeBytecodeBytes } from './effectAnalysis.js';
5
5
  import { lowerDxbcToIr } from './ir/lowerDxbcToIr.js';
@@ -16,13 +16,13 @@ const EFFECT_BACKEND_BODY_SET_CHUNK = "WGSB";
16
16
  const EFFECT_BACKEND_BODY_SET_FORMAT = "CJS_WGSL_BODY_SET";
17
17
  const EFFECT_BACKEND_BODY_SET_VERSION = 1;
18
18
 
19
- /**
20
- * One translation unit is exactly one pass of one body: the binding plan, the
21
- * resource-transform plan, and every stage's emitted WGSL are derived together.
22
- * Bodies that share an identical pass signature therefore share one unit.
23
- *
24
- * @param {object} pass Pass entry carrying its ordered stage records.
25
- * @returns {string} Stable signature for the pass translation unit.
19
+ /**
20
+ * One translation unit is exactly one pass of one body: the binding plan, the
21
+ * resource-transform plan, and every stage's emitted WGSL are derived together.
22
+ * Bodies that share an identical pass signature therefore share one unit.
23
+ *
24
+ * @param {object} pass Pass entry carrying its ordered stage records.
25
+ * @returns {string} Stable signature for the pass translation unit.
26
26
  */
27
27
  function passUnitSignature(pass) {
28
28
  return JSON.stringify({
@@ -157,19 +157,19 @@ function translatePassUnit(pass, programForKey, source, bindingPolicy) {
157
157
  })));
158
158
  }
159
159
 
160
- /**
161
- * Translate every unique source body into backend programs, layouts, and
162
- * resource transforms, sharing one translation unit between bodies whose pass
163
- * is byte-for-byte identical.
164
- *
160
+ /**
161
+ * Translate every unique source body into backend programs, layouts, and
162
+ * resource transforms, sharing one translation unit between bodies whose pass
163
+ * is byte-for-byte identical.
164
+ *
165
165
  * A body that cannot be lowered is retained as an explicitly unsupported
166
166
  * in-memory record carrying its reason. Portable source reflection is built
167
167
  * separately from the same effect; this body-set document does not store it.
168
- *
169
- * @param {object} effectRes Loaded version-15 `Tr2EffectRes`.
170
- * @param {object} permutationGraph Validated `PGRF` document.
171
- * @param {object} [options] Source label, stage selection, and binding policy.
172
- * @returns {object} Frozen `CJS_WGSL_BODY_SET` document.
168
+ *
169
+ * @param {object} effectRes Loaded version-15 `Tr2EffectRes`.
170
+ * @param {object} permutationGraph Validated `PGRF` document.
171
+ * @param {object} [options] Source label, stage selection, and binding policy.
172
+ * @returns {object} Frozen `CJS_WGSL_BODY_SET` document.
173
173
  */
174
174
  function buildEffectBackendBodySet(effectRes, permutationGraph, options = {}) {
175
175
  const source = options.source || "memory";