@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
@@ -6,7 +6,7 @@ import { compareUtf8 } from '../compareUtf8.js';
6
6
 
7
7
 
8
8
  /**
9
- * The only description-blob version this module reads or writes.
9
+ * The current description-blob version, and the only one this module writes.
10
10
  *
11
11
  * `DATA_VERSION` in `EffectData.h:10`. Carbon's reader accepts 2..15
12
12
  * (`Tr2EffectRes.cpp:209`) but annotates the v13/v14 field-order boundaries as
@@ -18,6 +18,18 @@ import { compareUtf8 } from '../compareUtf8.js';
18
18
  */
19
19
  const CARBON_EFFECT_DATA_VERSION = 15;
20
20
 
21
+ /**
22
+ * The oldest description-blob version this module reads.
23
+ *
24
+ * Carbon threads the version through parsing rather than gating on it twice,
25
+ * and its branches reach back to version 2. Maintainer decision, 2026-08-02:
26
+ * **8 is the lowest version worth reading** — the branches below 8 have no
27
+ * examined file, no writer, and no consumer, so restoring them would be code
28
+ * with no evidence. Reading a version is not supporting it: the reader's job
29
+ * ends at a correct record tree, normalized to the v15 record shape.
30
+ */
31
+ const CARBON_EFFECT_MIN_DATA_VERSION = 8;
32
+
21
33
  /**
22
34
  * Annotation type codes (`EffectData.h:35-41`). Only `STRING` changes the wire
23
35
  * shape of the value that follows.
@@ -348,19 +360,40 @@ function writeAnnotations(writer, arena, annotations) {
348
360
  }
349
361
  }
350
362
 
363
+ /**
364
+ * Maps a pre-v11 constant type byte onto the current enum
365
+ * (`Tr2EffectDescription.cpp:141-158`). The old wire knew FLOAT/INT/BOOL;
366
+ * the current numbering is FLOAT 0, INT 1, UINT 2, BOOL 3, OTHER 4.
367
+ *
368
+ * @param {number} value Pre-v11 type byte.
369
+ * @returns {number} Current constant type value.
370
+ */
371
+ function mapOldConstantType(value) {
372
+ if (value === 0) return 0;
373
+ if (value === 1) return 1;
374
+ if (value === 2) return 3;
375
+ return 4;
376
+ }
377
+
351
378
  /**
352
379
  * Reads one `Constant` (`EffectData.h:283-294`, `ReadConstant`
353
- * `Tr2EffectDescription.cpp:136-170`).
380
+ * `Tr2EffectDescription.cpp:136-170`). The byte layout is identical across
381
+ * versions 8..15; only the type byte's numbering changed at v11.
354
382
  *
355
383
  * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
384
+ * @param {number} version Container data version.
356
385
  * @returns {object} Constant record.
357
386
  */
358
- function readConstant(reader) {
387
+ function readConstant(reader, version) {
388
+ const name = readStringRef(reader);
389
+ const offset = reader.readUint32();
390
+ const size = reader.readUint32();
391
+ const rawType = reader.readUint8();
359
392
  return {
360
- name: readStringRef(reader),
361
- offset: reader.readUint32(),
362
- size: reader.readUint32(),
363
- type: reader.readUint8(),
393
+ name,
394
+ offset,
395
+ size,
396
+ type: version < 11 ? mapOldConstantType(rawType) : rawType,
364
397
  dimension: reader.readUint8(),
365
398
  elements: reader.readUint32(),
366
399
  isSRGB: reader.readUint8(),
@@ -389,16 +422,18 @@ function writeConstant(writer, arena, constant) {
389
422
  /**
390
423
  * Reads one `Texture` (`EffectData.h:320-328`, `ReadResource`
391
424
  * `Tr2EffectDescription.cpp:172-190`). `count` is the reader's
392
- * `arrayElements`.
425
+ * `arrayElements`; before v13 the field is not on the wire and Carbon
426
+ * defaults it to one element.
393
427
  *
394
428
  * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
429
+ * @param {number} version Container data version.
395
430
  * @returns {object} Texture record.
396
431
  */
397
- function readTexture(reader) {
432
+ function readTexture(reader, version) {
398
433
  return {
399
434
  name: readStringRef(reader),
400
435
  type: reader.readUint8(),
401
- count: reader.readUint32(),
436
+ count: version >= 13 ? reader.readUint32() : 1,
402
437
  isSRGB: reader.readUint8(),
403
438
  isAutoregister: reader.readUint8()
404
439
  };
@@ -430,13 +465,14 @@ function writeTexture(writer, arena, texture) {
430
465
  * comment exists to prevent.
431
466
  *
432
467
  * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
468
+ * @param {number} version Container data version.
433
469
  * @returns {object} UAV record.
434
470
  */
435
- function readUav(reader) {
471
+ function readUav(reader, version) {
436
472
  return {
437
473
  name: readStringRef(reader),
438
474
  type: reader.readUint8(),
439
- count: reader.readUint32(),
475
+ count: version >= 13 ? reader.readUint32() : 1,
440
476
  isAutoregister: reader.readUint8()
441
477
  };
442
478
  }
@@ -461,11 +497,17 @@ function writeUav(writer, arena, uav) {
461
497
  * at `:429`). Border colour here is four floats — unlike a static sampler,
462
498
  * where it is a one-byte enum.
463
499
  *
500
+ * `isDynamic` joined the wire at v13. For older versions the key is OMITTED
501
+ * from the record rather than synthesised: the concept did not exist, so any
502
+ * invented value would either lie or (via the v15 rule that a non-dynamic
503
+ * sampler's name is cleared) silently erase names a legacy file does carry.
504
+ *
464
505
  * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
506
+ * @param {number} version Container data version.
465
507
  * @returns {object} Sampler record.
466
508
  */
467
- function readSampler(reader) {
468
- return {
509
+ function readSampler(reader, version) {
510
+ const record = {
469
511
  name: readStringRef(reader),
470
512
  comparison: reader.readUint8(),
471
513
  minFilter: reader.readUint8(),
@@ -479,9 +521,12 @@ function readSampler(reader) {
479
521
  comparisonFunc: reader.readUint8(),
480
522
  borderColor: [reader.readFloat32(), reader.readFloat32(), reader.readFloat32(), reader.readFloat32()],
481
523
  minLOD: reader.readFloat32(),
482
- maxLOD: reader.readFloat32(),
483
- isDynamic: reader.readUint8()
524
+ maxLOD: reader.readFloat32()
484
525
  };
526
+ if (version > 12) {
527
+ record.isDynamic = reader.readUint8();
528
+ }
529
+ return record;
485
530
  }
486
531
 
487
532
  /**
@@ -565,39 +610,85 @@ function writeStaticSampler(writer, sampler) {
565
610
  }
566
611
 
567
612
  /**
568
- * Reads the `StageData` block: registers, static samplers, constants, default
569
- * constant values, textures, samplers, UAVs, annotations
570
- * (`StageData::Save` `EffectData.h:631-676`).
613
+ * Maps a pre-v10 register type byte onto the current register-type values
614
+ * (`Tr2EffectDescription.cpp:262-276`).
571
615
  *
572
- * Carbon's reader splits this single contiguous run across two functions —
573
- * `ReadRegisters` takes the first two sub-records
574
- * (`Tr2EffectDescription.cpp:258-367`) and `ReadInput` the remaining six
575
- * (`:369-472`). Keeping them adjacent here is what makes the split invisible.
616
+ * @param {number} value Pre-v10 register type byte.
617
+ * @returns {number} Current register type value.
618
+ */
619
+ function mapOldRegisterType(value) {
620
+ if (value === 0) return 0;
621
+ if (value === 1) return 36;
622
+ if (value === 2) return 68;
623
+ if (value === 3) return 1;
624
+ return 36;
625
+ }
626
+
627
+ /**
628
+ * Reads the register signature and (v13+) static-sampler table
629
+ * (`ReadRegisters`, `Tr2EffectDescription.cpp:258-367`).
630
+ *
631
+ * Before v13 a register carries only its type and index; Carbon defaults the
632
+ * count to one and the space to the stage type (`:340-343`), and the record is
633
+ * normalized here so consumers see one shape.
576
634
  *
577
635
  * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
578
- * @param {Function} makeError Error factory.
579
- * @returns {object} Stage data record.
636
+ * @param {number} version Container data version.
637
+ * @param {number} stageType Stage type owning the signature; only consulted
638
+ * for the pre-v13 register-space default.
639
+ * @returns {{registers:object[], staticSamplers:object[]}} Signature records.
580
640
  */
581
- function readStageData(reader, makeError) {
641
+ function readSignature(reader, version, stageType) {
582
642
  const registers = [];
583
643
  const registerCount = reader.readUint8();
584
644
  for (let index = 0; index < registerCount; index += 1) {
585
- registers.push({
586
- registerType: reader.readUint8(),
587
- registerIndex: reader.readUint32(),
588
- registerCount: reader.readUint32(),
589
- registerSpace: reader.readUint8()
590
- });
645
+ const rawType = reader.readUint8();
646
+ const registerType = version > 9 ? rawType : mapOldRegisterType(rawType);
647
+ const registerIndex = reader.readUint32();
648
+ if (version > 12) {
649
+ registers.push({
650
+ registerType,
651
+ registerIndex,
652
+ registerCount: reader.readUint32(),
653
+ registerSpace: reader.readUint8()
654
+ });
655
+ } else {
656
+ registers.push({
657
+ registerType,
658
+ registerIndex,
659
+ registerCount: 1,
660
+ registerSpace: stageType
661
+ });
662
+ }
591
663
  }
592
664
  const staticSamplers = [];
593
- const staticSamplerCount = reader.readUint8();
594
- for (let index = 0; index < staticSamplerCount; index += 1) {
595
- staticSamplers.push(readStaticSampler(reader));
665
+ if (version > 12) {
666
+ const staticSamplerCount = reader.readUint8();
667
+ for (let index = 0; index < staticSamplerCount; index += 1) {
668
+ staticSamplers.push(readStaticSampler(reader));
669
+ }
596
670
  }
671
+ return {
672
+ registers,
673
+ staticSamplers
674
+ };
675
+ }
676
+
677
+ /**
678
+ * Reads the resource half of a `StageData` block: constants, default constant
679
+ * values, textures, samplers, UAVs, annotations (`ReadInput`,
680
+ * `Tr2EffectDescription.cpp:369-472`).
681
+ *
682
+ * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
683
+ * @param {number} version Container data version.
684
+ * @param {Function} makeError Error factory.
685
+ * @returns {object} Stage resource records.
686
+ */
687
+ function readStageResources(reader, version, makeError) {
597
688
  const constants = [];
598
689
  const constantCount = reader.readUint32();
599
690
  for (let index = 0; index < constantCount; index += 1) {
600
- constants.push(readConstant(reader));
691
+ constants.push(readConstant(reader, version));
601
692
  }
602
693
  const defaultValues = readBlobRef(reader);
603
694
  const textures = [];
@@ -606,7 +697,7 @@ function readStageData(reader, makeError) {
606
697
  const registerIndex = reader.readUint8();
607
698
  textures.push({
608
699
  registerIndex,
609
- ...readTexture(reader)
700
+ ...readTexture(reader, version)
610
701
  });
611
702
  }
612
703
  const samplers = [];
@@ -615,7 +706,7 @@ function readStageData(reader, makeError) {
615
706
  const registerIndex = reader.readUint8();
616
707
  samplers.push({
617
708
  registerIndex,
618
- ...readSampler(reader)
709
+ ...readSampler(reader, version)
619
710
  });
620
711
  }
621
712
  const uavs = [];
@@ -624,12 +715,10 @@ function readStageData(reader, makeError) {
624
715
  const registerIndex = reader.readUint8();
625
716
  uavs.push({
626
717
  registerIndex,
627
- ...readUav(reader)
718
+ ...readUav(reader, version)
628
719
  });
629
720
  }
630
721
  return {
631
- registers,
632
- staticSamplers,
633
722
  constants,
634
723
  defaultValues,
635
724
  textures,
@@ -639,6 +728,31 @@ function readStageData(reader, makeError) {
639
728
  };
640
729
  }
641
730
 
731
+ /**
732
+ * Reads a whole `StageData` block: registers, static samplers, then the
733
+ * resource half (`StageData::Save` `EffectData.h:631-676`).
734
+ *
735
+ * Carbon's reader splits this single contiguous run across two functions —
736
+ * `ReadRegisters` takes the first two sub-records
737
+ * (`Tr2EffectDescription.cpp:258-367`) and `ReadInput` the remaining six
738
+ * (`:369-472`). The split exists here too, because before v14 the two halves
739
+ * are not adjacent on the wire — the signature precedes the program blob
740
+ * while the resources follow the thread-group size — and `readStage` places
741
+ * each half where its version put it.
742
+ *
743
+ * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
744
+ * @param {number} version Container data version.
745
+ * @param {Function} makeError Error factory.
746
+ * @param {number} stageType Stage type owning the signature.
747
+ * @returns {object} Stage data record.
748
+ */
749
+ function readStageData(reader, version, makeError, stageType) {
750
+ return {
751
+ ...readSignature(reader, version, stageType),
752
+ ...readStageResources(reader, version, makeError)
753
+ };
754
+ }
755
+
642
756
  /**
643
757
  * Writes the `StageData` block.
644
758
  *
@@ -688,6 +802,51 @@ function writeStageData(writer, arena, stageData) {
688
802
  writeAnnotations(writer, arena, stageData.annotations);
689
803
  }
690
804
 
805
+ /**
806
+ * Reads the pipeline-input list (`Tr2EffectDescription.cpp:234-256`).
807
+ *
808
+ * The `type`/`dimension` bytes joined the wire at v11; before that Carbon
809
+ * derives them — UINT for the blend-index usage, FLOAT otherwise, always four
810
+ * components (`:247-252`) — and the record is normalized here the same way.
811
+ *
812
+ * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
813
+ * @param {number} version Container data version.
814
+ * @param {Function} makeError Error factory.
815
+ * @returns {object[]} Pipeline-input records.
816
+ */
817
+ function readPipelineInputs(reader, version, makeError) {
818
+ const pipelineInputs = [];
819
+ const pipelineInputCount = sanityCheck(reader.readUint8(), "pipelineInputs", makeError);
820
+ for (let index = 0; index < pipelineInputCount; index += 1) {
821
+ const usage = reader.readUint8();
822
+ const registerIndex = reader.readUint8();
823
+ const usageIndex = reader.readUint8();
824
+ const usedMask = reader.readUint8();
825
+ if (version > 10) {
826
+ pipelineInputs.push({
827
+ usage,
828
+ registerIndex,
829
+ usageIndex,
830
+ usedMask,
831
+ type: reader.readUint8(),
832
+ dimension: reader.readUint8()
833
+ });
834
+ } else {
835
+ pipelineInputs.push({
836
+ usage,
837
+ registerIndex,
838
+ usageIndex,
839
+ usedMask,
840
+ // Constant-type values: 2 is UINT, 0 is FLOAT; usage 6 is the
841
+ // blend-index semantic.
842
+ type: usage === 6 ? 2 : 0,
843
+ dimension: 4
844
+ });
845
+ }
846
+ }
847
+ return pipelineInputs;
848
+ }
849
+
691
850
  /**
692
851
  * Reads one stage (`StageInput::Save` `EffectData.h:691-709`,
693
852
  * `Tr2EffectDescription.cpp:532-585`).
@@ -695,35 +854,47 @@ function writeStageData(writer, arena, stageData) {
695
854
  * At v15 the program payload comes first and the signature tables follow.
696
855
  * Before v14 it was the other way round; the reorder is the v14 change, and
697
856
  * Carbon marks its own v14 branch `// CHECK` (`:578`). Verified against the
698
- * writer: `type`, `shaderSize`, `shaderData`, `threadGroupSize[0..2]`,
699
- * `pipelineInputs`, then `StageData`.
857
+ * writer for v15: `type`, `shaderSize`, `shaderData`,
858
+ * `threadGroupSize[0..2]`, `pipelineInputs`, then `StageData`. Two further
859
+ * legacy wrinkles, both from Carbon's reader: a stage carries no register
860
+ * signature at all before v9 (`:544`), and two legacy dwords follow the
861
+ * program reference before v12, read and discarded (`:559-563`).
700
862
  *
701
863
  * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
864
+ * @param {number} version Container data version.
702
865
  * @param {Function} makeError Error factory.
703
866
  * @returns {object} Stage record.
704
867
  */
705
- function readStage(reader, makeError) {
868
+ function readStage(reader, version, makeError) {
706
869
  const type = reader.readUint8();
870
+ let pipelineInputs = [];
871
+ let signature = {
872
+ registers: [],
873
+ staticSamplers: []
874
+ };
875
+ if (version < 14) {
876
+ pipelineInputs = readPipelineInputs(reader, version, makeError);
877
+ if (version > 8) {
878
+ signature = readSignature(reader, version, type);
879
+ }
880
+ }
707
881
  const shaderData = readBlobRef(reader);
882
+ if (version < 12) {
883
+ reader.readUint32();
884
+ reader.readUint32();
885
+ }
708
886
  const threadGroupSize = [reader.readUint32(), reader.readUint32(), reader.readUint32()];
709
- const pipelineInputs = [];
710
- const pipelineInputCount = sanityCheck(reader.readUint8(), "pipelineInputs", makeError);
711
- for (let index = 0; index < pipelineInputCount; index += 1) {
712
- pipelineInputs.push({
713
- usage: reader.readUint8(),
714
- registerIndex: reader.readUint8(),
715
- usageIndex: reader.readUint8(),
716
- usedMask: reader.readUint8(),
717
- type: reader.readUint8(),
718
- dimension: reader.readUint8()
719
- });
887
+ if (version >= 14) {
888
+ pipelineInputs = readPipelineInputs(reader, version, makeError);
889
+ signature = readSignature(reader, version, type);
720
890
  }
721
891
  return {
722
892
  type,
723
893
  shaderData,
724
894
  threadGroupSize,
725
895
  pipelineInputs,
726
- ...readStageData(reader, makeError)
896
+ ...signature,
897
+ ...readStageResources(reader, version, makeError)
727
898
  };
728
899
  }
729
900
 
@@ -757,15 +928,16 @@ function writeStage(writer, arena, stage) {
757
928
  * Reads one pass (`Pass::Save` `EffectData.h:724-738`).
758
929
  *
759
930
  * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
931
+ * @param {number} version Container data version.
760
932
  * @param {Function} makeError Error factory.
761
933
  * @param {boolean} backend Whether the optional trailing block is present.
762
934
  * @returns {object} Pass record.
763
935
  */
764
- function readPass(reader, makeError, backend) {
936
+ function readPass(reader, version, makeError, backend) {
765
937
  const stages = [];
766
938
  const stageCount = sanityCheck(reader.readUint8(), "stages", makeError);
767
939
  for (let index = 0; index < stageCount; index += 1) {
768
- stages.push(readStage(reader, makeError));
940
+ stages.push(readStage(reader, version, makeError));
769
941
  }
770
942
  const renderStates = [];
771
943
  const stateCount = sanityCheck(reader.readUint8(), "renderStates", makeError);
@@ -818,10 +990,11 @@ function writePass(writer, arena, pass, backend) {
818
990
  * blocks and no pipeline inputs, thread group size, or stage type.
819
991
  *
820
992
  * @param {import("../CjsByteReader.js").CjsByteReader} reader Source reader.
993
+ * @param {number} version Container data version.
821
994
  * @param {Function} makeError Error factory.
822
995
  * @returns {object} Library record.
823
996
  */
824
- function readLibrary(reader, makeError) {
997
+ function readLibrary(reader, version, makeError) {
825
998
  const payloadSize = reader.readUint32();
826
999
  const shaderData = readBlobRef(reader);
827
1000
  const exports = [];
@@ -832,13 +1005,17 @@ function readLibrary(reader, makeError) {
832
1005
  name: readStringRef(reader)
833
1006
  });
834
1007
  }
1008
+
1009
+ // Libraries exist only from v14, so the pre-v13 register-space default in
1010
+ // the signature reader is unreachable here; the stage type it would need
1011
+ // is passed as zero.
835
1012
  return {
836
1013
  payloadSize,
837
1014
  shaderData,
838
1015
  exports,
839
1016
  hitGroupName: readStringRef(reader),
840
- globalInputs: readStageData(reader, makeError),
841
- localInputs: readStageData(reader, makeError)
1017
+ globalInputs: readStageData(reader, version, makeError, 0),
1018
+ localInputs: readStageData(reader, version, makeError, 0)
842
1019
  };
843
1020
  }
844
1021
 
@@ -870,6 +1047,10 @@ function writeLibrary(writer, arena, library) {
870
1047
  * @param {import("../CjsByteReader.js").CjsByteReader} reader Reader positioned at the blob.
871
1048
  * @param {object} [options] Read options.
872
1049
  * @param {Function} [options.makeError] Error factory taking a message and details.
1050
+ * @param {number} [options.version] Container data version; defaults to the
1051
+ * current version. Accepted range is `CARBON_EFFECT_MIN_DATA_VERSION` to
1052
+ * `CARBON_EFFECT_DATA_VERSION`; the record tree comes out normalized to
1053
+ * the v15 shape whatever the wire carried.
873
1054
  * @param {boolean} [options.backend] Expect our optional per-pass trailing block.
874
1055
  * Leave false for a Carbon file, which ends each pass at the render states.
875
1056
  * @returns {object} Description record tree.
@@ -877,6 +1058,12 @@ function writeLibrary(writer, arena, library) {
877
1058
  function readEffectDescription(reader, options = {}) {
878
1059
  const makeError = options.makeError ?? ((message, details) => reader._error(message, details));
879
1060
  const backend = options.backend === true;
1061
+ const version = Number.isInteger(options.version) ? options.version : CARBON_EFFECT_DATA_VERSION;
1062
+ if (version < CARBON_EFFECT_MIN_DATA_VERSION || version > CARBON_EFFECT_DATA_VERSION) {
1063
+ throw makeError(`Unsupported Carbon effect version ${version}; expected ${CARBON_EFFECT_MIN_DATA_VERSION}..${CARBON_EFFECT_DATA_VERSION}`, {
1064
+ version
1065
+ });
1066
+ }
880
1067
  const techniques = [];
881
1068
  const techniqueCount = reader.readUint8();
882
1069
  for (let techniqueIndex = 0; techniqueIndex < techniqueCount; techniqueIndex += 1) {
@@ -884,12 +1071,17 @@ function readEffectDescription(reader, options = {}) {
884
1071
  const passes = [];
885
1072
  const passCount = sanityCheck(reader.readUint8(), "passes", makeError);
886
1073
  for (let passIndex = 0; passIndex < passCount; passIndex += 1) {
887
- passes.push(readPass(reader, makeError, backend));
1074
+ passes.push(readPass(reader, version, makeError, backend));
888
1075
  }
1076
+
1077
+ // The library table joined the wire at v14; older files end the
1078
+ // technique at its passes.
889
1079
  const libraries = [];
890
- const libraryCount = reader.readUint8();
891
- for (let libraryIndex = 0; libraryIndex < libraryCount; libraryIndex += 1) {
892
- libraries.push(readLibrary(reader, makeError));
1080
+ if (version > 13) {
1081
+ const libraryCount = reader.readUint8();
1082
+ for (let libraryIndex = 0; libraryIndex < libraryCount; libraryIndex += 1) {
1083
+ libraries.push(readLibrary(reader, version, makeError));
1084
+ }
893
1085
  }
894
1086
  techniques.push({
895
1087
  name,
@@ -951,5 +1143,5 @@ function writeEffectDescription(writer, description, options = {}) {
951
1143
  return writer;
952
1144
  }
953
1145
 
954
- export { CARBON_ANNOTATION_TYPE, CARBON_EFFECT_COUNT_CAPS, CARBON_EFFECT_DATA_VERSION, CARBON_SHADER_CONSTANTS_MAX, collectArena, compareAnnotationNames, internArena, passthroughArena, readEffectDescription, writeEffectDescription };
1146
+ export { CARBON_ANNOTATION_TYPE, CARBON_EFFECT_COUNT_CAPS, CARBON_EFFECT_DATA_VERSION, CARBON_EFFECT_MIN_DATA_VERSION, CARBON_SHADER_CONSTANTS_MAX, collectArena, compareAnnotationNames, internArena, passthroughArena, readEffectDescription, writeEffectDescription };
955
1147
  //# sourceMappingURL=carbonEffectRecords.js.map