@carbonenginejs/runtime-resource 0.16.0 → 0.18.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 (54) hide show
  1. package/dist/format/CjsFormat.js +84 -83
  2. package/dist/format/CjsFormat.js.map +1 -1
  3. package/dist/format/CjsResourceProbe.js +87 -86
  4. package/dist/format/CjsResourceProbe.js.map +1 -1
  5. package/dist/format/carbonEffect/backendEngineId.js +98 -0
  6. package/dist/format/carbonEffect/backendEngineId.js.map +1 -0
  7. package/dist/format/carbonEffect/carbonEffectBackendBlock.js +24 -23
  8. package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -1
  9. package/dist/format/carbonEffect/carbonEffectResourceTransform.js +1 -1
  10. package/dist/format/carbonEffect/carbonEffectResourceTransform.js.map +1 -1
  11. package/dist/format/effect/effectPermutationGraph.js +46 -29
  12. package/dist/format/effect/effectPermutationGraph.js.map +1 -1
  13. package/dist/format/index.js +1 -1
  14. package/dist/formats/hlsl/core/detailMapFamily.js +1 -1
  15. package/dist/formats/hlsl/core/detailMapFamily.js.map +1 -1
  16. package/dist/formats/hlsl/core/localLightFamily.js +1 -1
  17. package/dist/formats/hlsl/core/localLightFamily.js.map +1 -1
  18. package/dist/formats/png/core/helpers.js +27 -8
  19. package/dist/formats/png/core/helpers.js.map +1 -1
  20. package/dist/formats/webgl/core/effectPackage.js +143 -56
  21. package/dist/formats/webgl/core/effectPackage.js.map +1 -1
  22. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +799 -456
  23. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
  24. package/dist/formats/webgl/core/glslBackendBlock.js +74 -30
  25. package/dist/formats/webgl/core/glslBackendBlock.js.map +1 -1
  26. package/dist/formats/webgl/core/glslBackendBodySet.js +0 -1
  27. package/dist/formats/webgl/core/glslBackendBodySet.js.map +1 -1
  28. package/dist/formats/webgl/core/helpers.js +53 -53
  29. package/dist/formats/webgl/core/helpers.js.map +1 -1
  30. package/dist/formats/webgl/core/readGlslEffectContainer.js +82 -67
  31. package/dist/formats/webgl/core/readGlslEffectContainer.js.map +1 -1
  32. package/dist/formats/webgpu/CjsWebgpuFormat.js +161 -163
  33. package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
  34. package/dist/formats/webgpu/core/carbonWebgpu/CarbonWebgpuContainer.js +10 -1
  35. package/dist/formats/webgpu/core/carbonWebgpu/CarbonWebgpuContainer.js.map +1 -1
  36. package/dist/formats/webgpu/core/effectBackendBodySet.js +21 -22
  37. package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
  38. package/dist/formats/webgpu/core/helpers.js +111 -99
  39. package/dist/formats/webgpu/core/helpers.js.map +1 -1
  40. package/dist/formats/webgpu/core/packageEffect.js +30 -32
  41. package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
  42. package/dist/formats/wem/CjsWemFormat.js +121 -121
  43. package/dist/formats/wem/CjsWemFormat.js.map +1 -1
  44. package/dist/formats/wem/core/resolve.js +8 -8
  45. package/dist/formats/wem/core/resolve.js.map +1 -1
  46. package/dist/resource/shader/reflection/Tr2EffectStageInput.js +102 -60
  47. package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
  48. package/docs/concepts/format-type-resolution.md +79 -0
  49. package/docs/formats/README.md +11 -0
  50. package/docs/formats/webgpu/formats/carbon-webgpu.md +11 -4
  51. package/docs/formats/webgpu/reference/api.md +7 -6
  52. package/docs/formats/wwise.md +25 -0
  53. package/docs/roadmap.md +19 -0
  54. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sources":["../../../../../src/formats/wem/core/resolve.js"],"sourcesContent":["// Content-verified codec resolution for wem media (kb §5 resolveType seam).\n// The fmt tag is the declaration; each candidate codec gets ONE bounded\n// structural check against the actual container facts - no audio is decoded:\n//\n// - wwise-vorbis: the Wwise Vorbis sidecar must exist (vorb chunk or inline\n// fmt-0x42 layout) with a positive sample count and data payload;\n// - wwise-ptadpcm: the frame layout must satisfy the decoder's own guard\n// (blockAlign = frameSize * channels, frameSize >= 6) with block-aligned\n// data;\n// - pcm / pcm-extensible: 16-bit with self-consistent blockAlign/byteRate\n// and sample-aligned data.\n//\n// The declared codec is validated FIRST; when its check fails (a mislabeled\n// tag), the other candidates are tried in order. A 2026-07-19 census of all\n// 8,987 embedded wems in EVE build 3435006 found no mislabeled tags, so\n// mismatch is the exceptional path - but the check is what makes that a\n// verified fact per file rather than a corpus-wide assumption.\nimport { inspectWithValues } from \"./helpers.js\";\n\nconst CANDIDATES = [ \"wwise-vorbis\", \"wwise-ptadpcm\", \"pcm\" ];\n\nfunction validateVorbis(metadata)\n{\n if (metadata.codec === \"wwise-vorbis\")\n {\n return metadata.vorbis !== null && metadata.sampleCount > 0 && metadata.dataBytes > 0;\n }\n // Mislabeled tag: inspect() only fills `vorbis` when the tag says so, but\n // the chunk walk always records a standalone vorb sidecar chunk.\n return (metadata.chunks ?? []).some(chunk => chunk.id === \"vorb\") && metadata.dataBytes > 0;\n}\n\nfunction validatePtadpcm(metadata)\n{\n const channels = metadata.channels;\n const frameSize = channels > 0 ? Math.floor(metadata.blockAlign / channels) : 0;\n return channels >= 1\n && frameSize >= 6\n && metadata.blockAlign === frameSize * channels\n && metadata.dataBytes >= metadata.blockAlign\n && metadata.dataBytes % metadata.blockAlign === 0;\n}\n\nfunction validatePcm(metadata)\n{\n return metadata.bitsPerSample === 16\n && metadata.channels >= 1\n && metadata.blockAlign === metadata.channels * 2\n && metadata.byteRate === metadata.sampleRate * metadata.blockAlign\n && metadata.dataBytes > 0\n && metadata.dataBytes % metadata.blockAlign === 0;\n}\n\nfunction validate(candidate, metadata)\n{\n if (candidate === \"wwise-vorbis\") return validateVorbis(metadata);\n if (candidate === \"wwise-ptadpcm\") return validatePtadpcm(metadata);\n return validatePcm(metadata);\n}\n\nfunction candidateFor(codec)\n{\n if (codec === \"pcm-extensible\") return \"pcm\";\n return CANDIDATES.includes(codec) ? codec : null;\n}\n\nfunction emitFor(candidate)\n{\n if (candidate === \"wwise-vorbis\") return \"ogg\";\n if (candidate === \"wwise-ptadpcm\" || candidate === \"pcm\") return \"pcm\";\n return \"raw\";\n}\n\n/**\n * Resolve a wem's actual decode route from content, not just its fmt tag.\n *\n * @param {*} input Wem bytes.\n * @param {object} values Normalized read values.\n * @returns {object} Probe-shaped report: verified variant flags, `preferred`\n * route, and declared/resolved/mismatch evidence in `metadata`.\n */\nexport function resolveTypeWithValues(input, values)\n{\n const metadata = inspectWithValues(input, values);\n const declared = metadata.codec || null;\n let resolved = null;\n const declaredCandidate = candidateFor(declared);\n if (declaredCandidate && validate(declaredCandidate, metadata))\n {\n resolved = declaredCandidate;\n }\n else\n {\n for (const candidate of CANDIDATES)\n {\n if (candidate === declaredCandidate) continue;\n if (validate(candidate, metadata))\n {\n resolved = candidate;\n break;\n }\n }\n }\n\n const preferred = emitFor(resolved);\n const mismatch = resolved !== null && declaredCandidate !== resolved;\n return {\n format: \"wem\",\n source: values.source || \"buffer\",\n supported: metadata.codec ? \"partial\" : \"none\",\n confidence: resolved ? 1 : 0,\n verified: true,\n preferred,\n reason: resolved\n ? (mismatch\n ? `Declared codec ${declared} failed content validation; ${resolved} validated instead.`\n : `Declared codec validated by content.`)\n : `No decodable codec validated against the content (declared ${declared ?? \"none\"}).`,\n metadata: { ...metadata, declared, resolved, mismatch },\n variants: [\n {\n kind: \"raw\",\n payloadType: \"raw\",\n codec: declared || \"unknown\",\n mimeType: \"application/octet-stream\",\n supported: true,\n containerOnly: true,\n isDecoded: false,\n pcmDecodeSupported: false\n },\n {\n kind: \"ogg\",\n payloadType: \"raw\",\n codec: \"vorbis\",\n mimeType: \"audio/ogg\",\n supported: resolved === \"wwise-vorbis\",\n containerOnly: true,\n isDecoded: false\n },\n {\n kind: \"pcm\",\n payloadType: \"pcm\",\n codec: \"float32\",\n supported: resolved === \"wwise-ptadpcm\" || resolved === \"pcm\",\n isDecoded: true,\n pcmDecodeSupported: resolved === \"wwise-ptadpcm\" || resolved === \"pcm\"\n }\n ]\n };\n}\n"],"names":["CANDIDATES","validateVorbis","metadata","codec","vorbis","sampleCount","dataBytes","chunks","some","chunk","id","validatePtadpcm","channels","frameSize","Math","floor","blockAlign","validatePcm","bitsPerSample","byteRate","sampleRate","validate","candidate","candidateFor","includes","emitFor","resolveTypeWithValues","input","values","inspectWithValues","declared","resolved","declaredCandidate","preferred","mismatch","format","source","supported","confidence","verified","reason","variants","kind","payloadType","mimeType","containerOnly","isDecoded","pcmDecodeSupported"],"mappings":"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"}
1
+ {"version":3,"file":"resolve.js","sources":["../../../../../src/formats/wem/core/resolve.js"],"sourcesContent":["// Content-verified codec resolution for wem media (resolveType seam; see docs/concepts/format-type-resolution.md).\r\n// The fmt tag is the declaration; each candidate codec gets ONE bounded\r\n// structural check against the actual container facts - no audio is decoded:\r\n//\r\n// - wwise-vorbis: the Wwise Vorbis sidecar must exist (vorb chunk or inline\r\n// fmt-0x42 layout) with a positive sample count and data payload;\r\n// - wwise-ptadpcm: the frame layout must satisfy the decoder's own guard\r\n// (blockAlign = frameSize * channels, frameSize >= 6) with block-aligned\r\n// data;\r\n// - pcm / pcm-extensible: 16-bit with self-consistent blockAlign/byteRate\r\n// and sample-aligned data.\r\n//\r\n// The declared codec is validated FIRST; when its check fails (a mislabeled\r\n// tag), the other candidates are tried in order. A 2026-07-19 census of all\r\n// 8,987 embedded wems in EVE build 3435006 found no mislabeled tags, so\r\n// mismatch is the exceptional path - but the check is what makes that a\r\n// verified fact per file rather than a corpus-wide assumption.\r\nimport { inspectWithValues } from \"./helpers.js\";\r\n\r\nconst CANDIDATES = [ \"wwise-vorbis\", \"wwise-ptadpcm\", \"pcm\" ];\r\n\r\nfunction validateVorbis(metadata)\r\n{\r\n if (metadata.codec === \"wwise-vorbis\")\r\n {\r\n return metadata.vorbis !== null && metadata.sampleCount > 0 && metadata.dataBytes > 0;\r\n }\r\n // Mislabeled tag: inspect() only fills `vorbis` when the tag says so, but\r\n // the chunk walk always records a standalone vorb sidecar chunk.\r\n return (metadata.chunks ?? []).some(chunk => chunk.id === \"vorb\") && metadata.dataBytes > 0;\r\n}\r\n\r\nfunction validatePtadpcm(metadata)\r\n{\r\n const channels = metadata.channels;\r\n const frameSize = channels > 0 ? Math.floor(metadata.blockAlign / channels) : 0;\r\n return channels >= 1\r\n && frameSize >= 6\r\n && metadata.blockAlign === frameSize * channels\r\n && metadata.dataBytes >= metadata.blockAlign\r\n && metadata.dataBytes % metadata.blockAlign === 0;\r\n}\r\n\r\nfunction validatePcm(metadata)\r\n{\r\n return metadata.bitsPerSample === 16\r\n && metadata.channels >= 1\r\n && metadata.blockAlign === metadata.channels * 2\r\n && metadata.byteRate === metadata.sampleRate * metadata.blockAlign\r\n && metadata.dataBytes > 0\r\n && metadata.dataBytes % metadata.blockAlign === 0;\r\n}\r\n\r\nfunction validate(candidate, metadata)\r\n{\r\n if (candidate === \"wwise-vorbis\") return validateVorbis(metadata);\r\n if (candidate === \"wwise-ptadpcm\") return validatePtadpcm(metadata);\r\n return validatePcm(metadata);\r\n}\r\n\r\nfunction candidateFor(codec)\r\n{\r\n if (codec === \"pcm-extensible\") return \"pcm\";\r\n return CANDIDATES.includes(codec) ? codec : null;\r\n}\r\n\r\nfunction emitFor(candidate)\r\n{\r\n if (candidate === \"wwise-vorbis\") return \"ogg\";\r\n if (candidate === \"wwise-ptadpcm\" || candidate === \"pcm\") return \"pcm\";\r\n return \"raw\";\r\n}\r\n\r\n/**\r\n * Resolve a wem's actual decode route from content, not just its fmt tag.\r\n *\r\n * @param {*} input Wem bytes.\r\n * @param {object} values Normalized read values.\r\n * @returns {object} Probe-shaped report: verified variant flags, `preferred`\r\n * route, and declared/resolved/mismatch evidence in `metadata`.\r\n */\r\nexport function resolveTypeWithValues(input, values)\r\n{\r\n const metadata = inspectWithValues(input, values);\r\n const declared = metadata.codec || null;\r\n let resolved = null;\r\n const declaredCandidate = candidateFor(declared);\r\n if (declaredCandidate && validate(declaredCandidate, metadata))\r\n {\r\n resolved = declaredCandidate;\r\n }\r\n else\r\n {\r\n for (const candidate of CANDIDATES)\r\n {\r\n if (candidate === declaredCandidate) continue;\r\n if (validate(candidate, metadata))\r\n {\r\n resolved = candidate;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n const preferred = emitFor(resolved);\r\n const mismatch = resolved !== null && declaredCandidate !== resolved;\r\n return {\r\n format: \"wem\",\r\n source: values.source || \"buffer\",\r\n supported: metadata.codec ? \"partial\" : \"none\",\r\n confidence: resolved ? 1 : 0,\r\n verified: true,\r\n preferred,\r\n reason: resolved\r\n ? (mismatch\r\n ? `Declared codec ${declared} failed content validation; ${resolved} validated instead.`\r\n : `Declared codec validated by content.`)\r\n : `No decodable codec validated against the content (declared ${declared ?? \"none\"}).`,\r\n metadata: { ...metadata, declared, resolved, mismatch },\r\n variants: [\r\n {\r\n kind: \"raw\",\r\n payloadType: \"raw\",\r\n codec: declared || \"unknown\",\r\n mimeType: \"application/octet-stream\",\r\n supported: true,\r\n containerOnly: true,\r\n isDecoded: false,\r\n pcmDecodeSupported: false\r\n },\r\n {\r\n kind: \"ogg\",\r\n payloadType: \"raw\",\r\n codec: \"vorbis\",\r\n mimeType: \"audio/ogg\",\r\n supported: resolved === \"wwise-vorbis\",\r\n containerOnly: true,\r\n isDecoded: false\r\n },\r\n {\r\n kind: \"pcm\",\r\n payloadType: \"pcm\",\r\n codec: \"float32\",\r\n supported: resolved === \"wwise-ptadpcm\" || resolved === \"pcm\",\r\n isDecoded: true,\r\n pcmDecodeSupported: resolved === \"wwise-ptadpcm\" || resolved === \"pcm\"\r\n }\r\n ]\r\n };\r\n}\r\n"],"names":["CANDIDATES","validateVorbis","metadata","codec","vorbis","sampleCount","dataBytes","chunks","some","chunk","id","validatePtadpcm","channels","frameSize","Math","floor","blockAlign","validatePcm","bitsPerSample","byteRate","sampleRate","validate","candidate","candidateFor","includes","emitFor","resolveTypeWithValues","input","values","inspectWithValues","declared","resolved","declaredCandidate","preferred","mismatch","format","source","supported","confidence","verified","reason","variants","kind","payloadType","mimeType","containerOnly","isDecoded","pcmDecodeSupported"],"mappings":"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"}
@@ -13,11 +13,11 @@ import { requireShaderStageType } from './shaderStage.js';
13
13
  // Source: trinity/trinity/Shader/Tr2EffectDescription.h
14
14
  // Source: trinity/trinity/Shader/Tr2EffectDescription.cpp
15
15
 
16
- /**
17
- * The offset word a zero-size blob carries, or the null sentinel.
18
- *
19
- * @param {{size:number,offset:number}} ref Blob reference.
20
- * @returns {number} Offset word worth retaining.
16
+ /**
17
+ * The offset word a zero-size blob carries, or the null sentinel.
18
+ *
19
+ * @param {{size:number,offset:number}} ref Blob reference.
20
+ * @returns {number} Offset word worth retaining.
21
21
  */
22
22
  function unsetOffsetOf(ref) {
23
23
  return ref.size === 0 ? ref.offset : 0xffffffff;
@@ -61,12 +61,54 @@ class Tr2EffectStageInput extends CjsModel {
61
61
  /** Exact source program metadata and owned bytes, before backend realization. */
62
62
  sourceProgram = null;
63
63
 
64
- /**
65
- * Construct one canonical stage input from JS/JSON model values.
66
- *
67
- * @param {object} values Canonical model values.
68
- * @param {object} options CjsModel import options.
69
- * @returns {Tr2EffectStageInput} Hydrated stage input.
64
+ // Ported from CarbonEngine (MIT, (c) 2026 CCP Games) - https://github.com/carbonengine/trinity
65
+ // trinity/Shader/Tr2Effect.cpp:1799-1821 (the sizing loop and its assertion)
66
+ //
67
+ // Carbon's comment at the site is the whole rule: "Figure out how large the
68
+ // constant buffer has to be. This has to be done even if the constant isn't
69
+ // set, as the shader may still sample it and expect to get some kind of
70
+ // default (usually zero)." So EVERY constant participates, not only the ones
71
+ // an effect binds a parameter to.
72
+ //
73
+ // THIS IS NOT `constantValueSize`, AND THE DIFFERENCE IS EASY TO MISS.
74
+ // `constantValueSize` is the length of the authored DEFAULT blob, which
75
+ // Carbon separately grows to cover autoregister sampler-index constants
76
+ // (Tr2EffectDescription.cpp:629-632). Carbon asserts
77
+ // `constantSize >= constantDefaultValueSize` precisely because the two are
78
+ // different numbers and the defaults are a PREFIX of the buffer. An effect
79
+ // that authors defaults for only some of its constants makes them differ, so
80
+ // using the default size as the buffer size is right until it silently is
81
+ // not.
82
+ //
83
+ // It lives here rather than in a consumer because it is arithmetic over this
84
+ // object's own constants and gives every backend the same answer. A backend
85
+ // then applies its own alignment on top - WebGPU's uniform binding alignment,
86
+ // std140 for a WebGL2 block - and that padding is the backend's, not this.
87
+ // Decision 4 of the engine backends plan names the alternative as a defect
88
+ // worth declining to inherit: Carbon replicates its draw-argument arithmetic
89
+ // across ten call sites, and this would replicate the same way once a second
90
+ // engine exists.
91
+
92
+ /**
93
+ * The byte size a constant buffer must have to hold every declared constant.
94
+ *
95
+ * Always at least `constantValueSize`, because the authored defaults occupy
96
+ * the start of the same buffer.
97
+ */
98
+ GetConstantBufferSize() {
99
+ let size = 0;
100
+ for (const constant of this.constants) {
101
+ size = Math.max(size, (constant?.offset ?? 0) + (constant?.size ?? 0));
102
+ }
103
+ return Math.max(size, this.constantValueSize);
104
+ }
105
+
106
+ /**
107
+ * Construct one canonical stage input from JS/JSON model values.
108
+ *
109
+ * @param {object} values Canonical model values.
110
+ * @param {object} options CjsModel import options.
111
+ * @returns {Tr2EffectStageInput} Hydrated stage input.
70
112
  */
71
113
  static from(values = {}, options = {}) {
72
114
  let normalized = values;
@@ -87,11 +129,11 @@ class Tr2EffectStageInput extends CjsModel {
87
129
  return stage;
88
130
  }
89
131
 
90
- /**
91
- * Hydrate one canonical stage input from a decoded Carbon binary record.
92
- *
93
- * @param {object} record Decoded Carbon stage record.
94
- * @returns {Tr2EffectStageInput} Hydrated canonical stage input.
132
+ /**
133
+ * Hydrate one canonical stage input from a decoded Carbon binary record.
134
+ *
135
+ * @param {object} record Decoded Carbon stage record.
136
+ * @returns {Tr2EffectStageInput} Hydrated canonical stage input.
95
137
  */
96
138
  static fromCarbonBinary(record) {
97
139
  if (!isPlainObject(record)) {
@@ -124,22 +166,22 @@ class Tr2EffectStageInput extends CjsModel {
124
166
  return input;
125
167
  }
126
168
 
127
- /**
128
- * Build one stage input from a Carbon v15 `StageData` block.
129
- *
130
- * A raytracing library's global and local inputs are the same block without a
131
- * stage wrapper — no stage type, no pipeline inputs, no thread group, no
132
- * program of their own — so this is the half both callers share and
133
- * `fromCarbonBinary` is the stage-only remainder layered on top.
134
- *
135
- * Carbon writes textures, samplers and UAVs in ascending register order because
136
- * they are `std::map`s, and they are re-keyed by register here rather than by
137
- * position, so the map is authoritative and the record's order is not load
138
- * bearing.
139
- *
140
- * @param {object} record Carbon stage-data record.
141
- * @param {number} [stageType] Stage index, or -1 for a library input.
142
- * @returns {Tr2EffectStageInput} Reflected stage input.
169
+ /**
170
+ * Build one stage input from a Carbon v15 `StageData` block.
171
+ *
172
+ * A raytracing library's global and local inputs are the same block without a
173
+ * stage wrapper — no stage type, no pipeline inputs, no thread group, no
174
+ * program of their own — so this is the half both callers share and
175
+ * `fromCarbonBinary` is the stage-only remainder layered on top.
176
+ *
177
+ * Carbon writes textures, samplers and UAVs in ascending register order because
178
+ * they are `std::map`s, and they are re-keyed by register here rather than by
179
+ * position, so the map is authoritative and the record's order is not load
180
+ * bearing.
181
+ *
182
+ * @param {object} record Carbon stage-data record.
183
+ * @param {number} [stageType] Stage index, or -1 for a library input.
184
+ * @returns {Tr2EffectStageInput} Reflected stage input.
143
185
  */
144
186
  static fromCarbonBinaryInput(record, stageType = -1) {
145
187
  if (!isPlainObject(record)) {
@@ -205,10 +247,10 @@ class Tr2EffectStageInput extends CjsModel {
205
247
  return input;
206
248
  }
207
249
 
208
- /**
209
- * Emit this stage as a Carbon v15 stage record.
210
- *
211
- * @returns {object} Carbon stage record.
250
+ /**
251
+ * Emit this stage as a Carbon v15 stage record.
252
+ *
253
+ * @returns {object} Carbon stage record.
212
254
  */
213
255
  toCarbonBinary() {
214
256
  const signature = this.signature ?? {};
@@ -229,17 +271,17 @@ class Tr2EffectStageInput extends CjsModel {
229
271
  };
230
272
  }
231
273
 
232
- /**
233
- * Emit this input as a Carbon v15 `StageData` block.
234
- *
235
- * Carbon holds textures, samplers, UAVs and render states in `std::map`s and
236
- * writes them in key order, and it sorts annotation names by `strcmp` before
237
- * writing. Our maps are keyed but not ordered, so every collection is sorted
238
- * explicitly here rather than trusting insertion order — the reader is
239
- * indifferent, but the bytes are not, and a container that disagrees with
240
- * Carbon's ordering is not the file Carbon would have written.
241
- *
242
- * @returns {object} Carbon stage-data record.
274
+ /**
275
+ * Emit this input as a Carbon v15 `StageData` block.
276
+ *
277
+ * Carbon holds textures, samplers, UAVs and render states in `std::map`s and
278
+ * writes them in key order, and it sorts annotation names by `strcmp` before
279
+ * writing. Our maps are keyed but not ordered, so every collection is sorted
280
+ * explicitly here rather than trusting insertion order — the reader is
281
+ * indifferent, but the bytes are not, and a container that disagrees with
282
+ * Carbon's ordering is not the file Carbon would have written.
283
+ *
284
+ * @returns {object} Carbon stage-data record.
243
285
  */
244
286
  toCarbonBinaryInput() {
245
287
  const byRegister = (left, right) => left.registerIndex - right.registerIndex;
@@ -305,11 +347,11 @@ class Tr2EffectStageInput extends CjsModel {
305
347
  return result;
306
348
  }
307
349
 
308
- /**
309
- * Create one explicit absent stage slot.
310
- *
311
- * @param {number} stageType Stage index.
312
- * @returns {Tr2EffectStageInput} Empty stage input.
350
+ /**
351
+ * Create one explicit absent stage slot.
352
+ *
353
+ * @param {number} stageType Stage index.
354
+ * @returns {Tr2EffectStageInput} Empty stage input.
313
355
  */
314
356
  static createEmpty(stageType) {
315
357
  const stage = new this();
@@ -317,14 +359,14 @@ class Tr2EffectStageInput extends CjsModel {
317
359
  return stage;
318
360
  }
319
361
 
320
- /**
321
- * Normalize one register-indexed collection into its canonical typed map.
322
- *
323
- * @param {Map|object} values Register-indexed source values.
324
- * @param {Function} Constructor Entry constructor exposing `from`.
325
- * @param {object} options Hydration options passed to entry construction.
326
- * @param {string} field Diagnostic field name.
327
- * @returns {Map<number, *>} Canonical register map.
362
+ /**
363
+ * Normalize one register-indexed collection into its canonical typed map.
364
+ *
365
+ * @param {Map|object} values Register-indexed source values.
366
+ * @param {Function} Constructor Entry constructor exposing `from`.
367
+ * @param {object} options Hydration options passed to entry construction.
368
+ * @param {string} field Diagnostic field name.
369
+ * @returns {Map<number, *>} Canonical register map.
328
370
  */
329
371
  static readCanonicalRegisterMap(values, Constructor, options, field) {
330
372
  const entries = values instanceof Map ? values : Object.entries(values ?? {});
@@ -1 +1 @@
1
- {"version":3,"file":"Tr2EffectStageInput.js","sources":["../../../../../src/resource/shader/reflection/Tr2EffectStageInput.js"],"sourcesContent":["// Source: trinity/trinity/Shader/Tr2EffectDescription.h\n// Source: trinity/trinity/Shader/Tr2EffectDescription.cpp\nimport { CjsSchema, impl, type } from \"@carbonenginejs/runtime-utils/schema\";\nimport { CjsModel } from \"@carbonenginejs/runtime-utils/model\";\nimport { copyBytes } from \"@carbonenginejs/runtime-utils/bytes\";\nimport {\n isPlainObject,\n isUint32\n} from \"@carbonenginejs/runtime-utils/is\";\nimport { Tr2SamplerSetup } from \"../sampler/Tr2SamplerSetup.js\";\nimport { Tr2EffectConstant } from \"./Tr2EffectConstant.js\";\nimport { Tr2EffectParameterAnnotation } from \"./Tr2EffectParameterAnnotation.js\";\nimport { Tr2EffectResource } from \"./Tr2EffectResource.js\";\nimport {\n recordBytes,\n recordRawBits,\n toRecordBlob,\n toRecordFloat,\n toRecordText\n} from \"./carbonRecordFields.js\";\nimport { compareUtf8 } from \"../../../format/compareUtf8.js\";\nimport { requireShaderStageType } from \"./shaderStage.js\";\n\n/**\n * The offset word a zero-size blob carries, or the null sentinel.\n *\n * @param {{size:number,offset:number}} ref Blob reference.\n * @returns {number} Offset word worth retaining.\n */\nfunction unsetOffsetOf(ref)\n{\n return ref.size === 0 ? ref.offset : 0xffffffff;\n}\n\n/** Complete device-free reflection for one shader stage input. */\nexport class Tr2EffectStageInput extends CjsModel\n{\n\n /** Portable stage index; Carbon otherwise implies this from the containing array. */\n stageType = -1;\n\n /** m_exists (bool) */\n exists = false;\n\n /** resources (Tr2EffectResourceMap) */\n resources = new Map();\n\n /** uavs (Tr2EffectResourceMap) */\n uavs = new Map();\n\n /** samplers (Tr2SamplerSetupMap) */\n samplers = new Map();\n\n /** m_shader (unsigned) */\n shader = 0xffffffff;\n\n /** constants (Tr2EffectConstantVector) */\n constants = [];\n\n /** m_constantValueSize (unsigned) */\n constantValueSize = 0;\n\n /** constantValues (char[SHADER_CONSTANTS_MAX]) */\n constantValues = new Uint8Array(0);\n\n /** signature (Tr2ShaderSignatureAL) */\n signature = null;\n\n /** annotation (Tr2EffectParameterAnnotationMap) */\n annotation = [];\n\n /** Exact source program metadata and owned bytes, before backend realization. */\n sourceProgram = null;\n\n /**\n * Construct one canonical stage input from JS/JSON model values.\n *\n * @param {object} values Canonical model values.\n * @param {object} options CjsModel import options.\n * @returns {Tr2EffectStageInput} Hydrated stage input.\n */\n static from(values = {}, options = {})\n {\n let normalized = values;\n const maps = new Map();\n for (const [ field, Constructor ] of [\n [ \"resources\", Tr2EffectResource ],\n [ \"uavs\", Tr2EffectResource ],\n [ \"samplers\", Tr2SamplerSetup ]\n ])\n {\n if (values && Object.hasOwn(values, field))\n {\n normalized = normalized === values ? { ...values } : normalized;\n normalized[field] = this.readCanonicalRegisterMap(\n values[field],\n Constructor,\n options,\n field\n );\n maps.set(field, normalized[field]);\n }\n }\n const stage = super.from(normalized, options);\n for (const [ field, value ] of maps)\n {\n stage[field] = value;\n }\n return stage;\n }\n\n /**\n * Hydrate one canonical stage input from a decoded Carbon binary record.\n *\n * @param {object} record Decoded Carbon stage record.\n * @returns {Tr2EffectStageInput} Hydrated canonical stage input.\n */\n static fromCarbonBinary(record)\n {\n if (!isPlainObject(record))\n {\n throw new TypeError(\"Carbon effect stage record must be an object\");\n }\n\n const input = this.fromCarbonBinaryInput(record, record.type);\n input.signature.pipelineInputCount = record.pipelineInputs.length;\n input.signature.pipelineInputs = record.pipelineInputs.map(entry => ({\n usage: entry.usage,\n registerIndex: entry.registerIndex,\n usageIndex: entry.usageIndex,\n usedMask: entry.usedMask,\n type: entry.type,\n dimension: entry.dimension\n }));\n input.signature.threadGroupSize = {\n x: record.threadGroupSize[0],\n y: record.threadGroupSize[1],\n z: record.threadGroupSize[2]\n };\n input.sourceProgram = {\n kind: \"stage\",\n bytes: copyBytes(recordBytes(record.shaderData)),\n shaderSize: record.shaderData.size,\n // Meaningful only at size zero, where the writer passes the word through\n // rather than interning. At any other size it is a live arena offset that\n // belongs to the container it was read from, so it is not retained.\n unsetOffset: unsetOffsetOf(record.shaderData)\n };\n return input;\n }\n\n /**\n * Build one stage input from a Carbon v15 `StageData` block.\n *\n * A raytracing library's global and local inputs are the same block without a\n * stage wrapper — no stage type, no pipeline inputs, no thread group, no\n * program of their own — so this is the half both callers share and\n * `fromCarbonBinary` is the stage-only remainder layered on top.\n *\n * Carbon writes textures, samplers and UAVs in ascending register order because\n * they are `std::map`s, and they are re-keyed by register here rather than by\n * position, so the map is authoritative and the record's order is not load\n * bearing.\n *\n * @param {object} record Carbon stage-data record.\n * @param {number} [stageType] Stage index, or -1 for a library input.\n * @returns {Tr2EffectStageInput} Reflected stage input.\n */\n static fromCarbonBinaryInput(record, stageType = -1)\n {\n if (!isPlainObject(record))\n {\n throw new TypeError(\"Carbon effect stage-data record must be an object\");\n }\n\n const constantValues = copyBytes(recordBytes(record.defaultValues));\n\n const input = new this();\n input.stageType = stageType;\n input.exists = true;\n input.constants = record.constants.map(\n entry => Tr2EffectConstant.fromCarbonBinary(entry)\n );\n input.resources = this.readCarbonBinaryResourceMap(record.textures);\n input.uavs = this.readCarbonBinaryResourceMap(record.uavs);\n input.samplers = this.readCarbonBinarySamplerMap(record.samplers);\n input.constantValueSize = constantValues.byteLength;\n input.constantValues = constantValues;\n input.constantValuesUnsetOffset = unsetOffsetOf(record.defaultValues);\n input.annotation = record.annotations.map(\n entry => Tr2EffectParameterAnnotation.fromCarbonBinary(entry)\n );\n input.signature = {\n pipelineInputCount: 0,\n pipelineInputs: [],\n registerCount: record.registers.length,\n // Carbon stores one field its reader calls `arrayCount` and its writer\n // calls `registerCount`. Both names are carried forward from the single\n // stored value, because the write direction refuses to emit a record whose\n // two names disagree.\n registers: record.registers.map(entry => ({\n registerType: entry.registerType,\n registerIndex: entry.registerIndex,\n arrayCount: entry.registerCount,\n registerCount: entry.registerCount,\n registerSpace: entry.registerSpace\n })),\n staticSamplerCount: record.staticSamplers.length,\n staticSamplers: record.staticSamplers.map(entry => ({\n registerIndex: entry.registerIndex,\n registerSpace: entry.registerSpace,\n descriptor: {\n comparison: !!entry.comparison,\n minFilter: entry.minFilter,\n magFilter: entry.magFilter,\n mipFilter: entry.mipFilter,\n addressU: entry.addressU,\n addressV: entry.addressV,\n addressW: entry.addressW,\n mipLODBiasRaw: recordRawBits(entry.mipLODBias),\n maxAnisotropy: entry.maxAnisotropy,\n comparisonFunc: entry.comparisonFunc,\n // A static sampler's border colour is a one-byte enum, not four\n // floats. Sharing the dynamic sampler's mapping here would silently\n // reinterpret it.\n borderColor: entry.borderColor,\n minLODRaw: recordRawBits(entry.minLOD),\n maxLODRaw: recordRawBits(entry.maxLOD)\n }\n })),\n threadGroupSize: { x: 0, y: 0, z: 0 }\n };\n input.sourceProgram = null;\n return input;\n }\n\n /**\n * Emit this stage as a Carbon v15 stage record.\n *\n * @returns {object} Carbon stage record.\n */\n toCarbonBinary()\n {\n const signature = this.signature ?? {};\n const program = this.sourceProgram ?? {};\n return {\n type: this.stageType,\n shaderData: toRecordBlob(\n program.bytes,\n program.shaderSize,\n program.unsetOffset\n ),\n threadGroupSize: [\n signature.threadGroupSize?.x ?? 0,\n signature.threadGroupSize?.y ?? 0,\n signature.threadGroupSize?.z ?? 0\n ],\n pipelineInputs: (signature.pipelineInputs ?? []).map(entry => ({\n usage: entry.usage,\n registerIndex: entry.registerIndex,\n usageIndex: entry.usageIndex,\n usedMask: entry.usedMask,\n type: entry.type,\n dimension: entry.dimension\n })),\n ...this.toCarbonBinaryInput()\n };\n }\n\n /**\n * Emit this input as a Carbon v15 `StageData` block.\n *\n * Carbon holds textures, samplers, UAVs and render states in `std::map`s and\n * writes them in key order, and it sorts annotation names by `strcmp` before\n * writing. Our maps are keyed but not ordered, so every collection is sorted\n * explicitly here rather than trusting insertion order — the reader is\n * indifferent, but the bytes are not, and a container that disagrees with\n * Carbon's ordering is not the file Carbon would have written.\n *\n * @returns {object} Carbon stage-data record.\n */\n toCarbonBinaryInput()\n {\n const byRegister = (left, right) => left.registerIndex - right.registerIndex;\n const signature = this.signature ?? {};\n return {\n registers: (signature.registers ?? []).map(entry => ({\n registerType: entry.registerType,\n registerIndex: entry.registerIndex,\n registerCount: entry.registerCount,\n registerSpace: entry.registerSpace\n })),\n staticSamplers: (signature.staticSamplers ?? []).map(entry =>\n {\n const descriptor = entry.descriptor ?? {};\n return {\n registerIndex: entry.registerIndex,\n registerSpace: entry.registerSpace,\n comparison: descriptor.comparison ? 1 : 0,\n minFilter: descriptor.minFilter,\n magFilter: descriptor.magFilter,\n mipFilter: descriptor.mipFilter,\n addressU: descriptor.addressU,\n addressV: descriptor.addressV,\n addressW: descriptor.addressW,\n mipLODBias: toRecordFloat(descriptor.mipLODBiasRaw),\n maxAnisotropy: descriptor.maxAnisotropy,\n comparisonFunc: descriptor.comparisonFunc,\n // One byte here, four floats on a dynamic sampler.\n borderColor: descriptor.borderColor,\n minLOD: toRecordFloat(descriptor.minLODRaw),\n maxLOD: toRecordFloat(descriptor.maxLODRaw)\n };\n }),\n constants: this.constants.map(constant => constant.toCarbonBinary()),\n defaultValues: toRecordBlob(\n this.constantValues,\n this.constantValueSize,\n this.constantValuesUnsetOffset\n ),\n textures: Array.from(this.resources, ([ register, resource ]) =>\n resource.toCarbonBinary(register)).sort(byRegister),\n samplers: Array.from(this.samplers, ([ register, sampler ]) =>\n sampler.toCarbonBinary(register)).sort(byRegister),\n uavs: Array.from(this.uavs, ([ register, uav ]) =>\n uav.toCarbonBinary(register, true)).sort(byRegister),\n annotations: this.annotation\n .map(entry => entry.toCarbonBinary())\n .sort((left, right) => compareUtf8(left.name.value, right.name.value))\n };\n }\n\n /** Build one register-indexed resource map from Carbon texture or UAV records. */\n static readCarbonBinaryResourceMap(records)\n {\n const result = new Map();\n for (const record of records)\n {\n if (result.has(record.registerIndex))\n {\n throw new Error(\n `Carbon effect resource register ${record.registerIndex} is duplicated`\n );\n }\n result.set(\n record.registerIndex,\n Tr2EffectResource.fromCarbonBinary(record)\n );\n }\n return result;\n }\n\n /** Build one register-indexed sampler map from Carbon sampler records. */\n static readCarbonBinarySamplerMap(records)\n {\n const result = new Map();\n for (const record of records)\n {\n if (result.has(record.registerIndex))\n {\n throw new Error(\n `Carbon effect sampler register ${record.registerIndex} is duplicated`\n );\n }\n result.set(\n record.registerIndex,\n Tr2SamplerSetup.fromCarbonBinary(record)\n );\n }\n return result;\n }\n\n /**\n * Create one explicit absent stage slot.\n *\n * @param {number} stageType Stage index.\n * @returns {Tr2EffectStageInput} Empty stage input.\n */\n static createEmpty(stageType)\n {\n const stage = new this();\n stage.stageType = requireShaderStageType(stageType);\n return stage;\n }\n\n /**\n * Normalize one register-indexed collection into its canonical typed map.\n *\n * @param {Map|object} values Register-indexed source values.\n * @param {Function} Constructor Entry constructor exposing `from`.\n * @param {object} options Hydration options passed to entry construction.\n * @param {string} field Diagnostic field name.\n * @returns {Map<number, *>} Canonical register map.\n */\n static readCanonicalRegisterMap(values, Constructor, options, field)\n {\n const entries = values instanceof Map\n ? values\n : Object.entries(values ?? {});\n const result = new Map();\n for (const [ key, value ] of entries)\n {\n const registerIndex = Number(key);\n if (!isUint32(registerIndex))\n {\n throw new RangeError(\n `Effect ${field} register index must fit uint32`\n );\n }\n if (result.has(registerIndex))\n {\n throw new Error(\n `Effect ${field} register ${registerIndex} is duplicated`\n );\n }\n result.set(\n registerIndex,\n value instanceof Constructor\n ? value\n : Constructor.from(value, options)\n );\n }\n return result;\n }\n\n}\n\n// Declared imperatively rather than with decorators, so this module stays\n// plain ESM that loads from source without a transform. The decorator\n// expressions are reused verbatim, so the registered metadata is identical.\n// Statics belong in `methods`: decorateMethod targets the prototype and\n// would register a static as an instance field.\nCjsSchema.define(Tr2EffectStageInput, {\n className: \"Tr2EffectStageInput\",\n family: \"shader\",\n fields: {\n stageType: [ impl.adapted, impl.reason(\"The source format identifies stage inputs by array index; the device-free graph retains the index explicitly for serialization and engine adapters.\"), type.int32 ],\n exists: type.boolean,\n resources: type.map(\"Tr2EffectResource\"),\n uavs: type.map(\"Tr2EffectResource\"),\n samplers: type.map(\"Tr2SamplerSetup\"),\n shader: type.uint32,\n constants: type.list(\"Tr2EffectConstant\"),\n constantValueSize: type.uint32,\n constantValues: type.typedArray(\"Uint8Array\"),\n constantValuesUnsetOffset: [ impl.custom, impl.reason(\"A zero-size blob's offset word is passed through rather than interned, and the shipped corpus does not always set it to the null sentinel; the graph retains it so a body re-emits as the file that produced it.\"), type.uint32 ],\n signature: type.rawStruct(\"Tr2ShaderSignatureAL\"),\n annotation: type.list(\"Tr2EffectParameterAnnotation\"),\n sourceProgram: [ impl.adapted, impl.reason(\"Carbon replaces source program data with renderer handles while reading; the device-free resource graph must retain the portable source program for later engine realization.\"), type.rawStruct(\"CjsEffectSourceProgram\") ]\n }\n});\n"],"names":["unsetOffsetOf","ref","size","offset","Tr2EffectStageInput","CjsModel","stageType","exists","resources","Map","uavs","samplers","shader","constants","constantValueSize","constantValues","Uint8Array","signature","annotation","sourceProgram","from","values","options","normalized","maps","field","Constructor","Tr2EffectResource","Tr2SamplerSetup","Object","hasOwn","readCanonicalRegisterMap","set","stage","value","fromCarbonBinary","record","isPlainObject","TypeError","input","fromCarbonBinaryInput","type","pipelineInputCount","pipelineInputs","length","map","entry","usage","registerIndex","usageIndex","usedMask","dimension","threadGroupSize","x","y","z","kind","bytes","copyBytes","recordBytes","shaderData","shaderSize","unsetOffset","defaultValues","Tr2EffectConstant","readCarbonBinaryResourceMap","textures","readCarbonBinarySamplerMap","byteLength","constantValuesUnsetOffset","annotations","Tr2EffectParameterAnnotation","registerCount","registers","registerType","arrayCount","registerSpace","staticSamplerCount","staticSamplers","descriptor","comparison","minFilter","magFilter","mipFilter","addressU","addressV","addressW","mipLODBiasRaw","recordRawBits","mipLODBias","maxAnisotropy","comparisonFunc","borderColor","minLODRaw","minLOD","maxLODRaw","maxLOD","toCarbonBinary","program","toRecordBlob","toCarbonBinaryInput","byRegister","left","right","toRecordFloat","constant","Array","register","resource","sort","sampler","uav","compareUtf8","name","records","result","has","Error","createEmpty","requireShaderStageType","entries","key","Number","isUint32","RangeError","CjsSchema","define","className","family","fields","impl","adapted","reason","int32","boolean","uint32","list","typedArray","custom","rawStruct"],"mappings":"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"}
1
+ {"version":3,"file":"Tr2EffectStageInput.js","sources":["../../../../../src/resource/shader/reflection/Tr2EffectStageInput.js"],"sourcesContent":["// Source: trinity/trinity/Shader/Tr2EffectDescription.h\r\n// Source: trinity/trinity/Shader/Tr2EffectDescription.cpp\r\nimport { CjsSchema, impl, type } from \"@carbonenginejs/runtime-utils/schema\";\r\nimport { CjsModel } from \"@carbonenginejs/runtime-utils/model\";\r\nimport { copyBytes } from \"@carbonenginejs/runtime-utils/bytes\";\r\nimport {\r\n isPlainObject,\r\n isUint32\r\n} from \"@carbonenginejs/runtime-utils/is\";\r\nimport { Tr2SamplerSetup } from \"../sampler/Tr2SamplerSetup.js\";\r\nimport { Tr2EffectConstant } from \"./Tr2EffectConstant.js\";\r\nimport { Tr2EffectParameterAnnotation } from \"./Tr2EffectParameterAnnotation.js\";\r\nimport { Tr2EffectResource } from \"./Tr2EffectResource.js\";\r\nimport {\r\n recordBytes,\r\n recordRawBits,\r\n toRecordBlob,\r\n toRecordFloat,\r\n toRecordText\r\n} from \"./carbonRecordFields.js\";\r\nimport { compareUtf8 } from \"../../../format/compareUtf8.js\";\r\nimport { requireShaderStageType } from \"./shaderStage.js\";\r\n\r\n/**\r\n * The offset word a zero-size blob carries, or the null sentinel.\r\n *\r\n * @param {{size:number,offset:number}} ref Blob reference.\r\n * @returns {number} Offset word worth retaining.\r\n */\r\nfunction unsetOffsetOf(ref)\r\n{\r\n return ref.size === 0 ? ref.offset : 0xffffffff;\r\n}\r\n\r\n/** Complete device-free reflection for one shader stage input. */\r\nexport class Tr2EffectStageInput extends CjsModel\r\n{\r\n\r\n /** Portable stage index; Carbon otherwise implies this from the containing array. */\r\n stageType = -1;\r\n\r\n /** m_exists (bool) */\r\n exists = false;\r\n\r\n /** resources (Tr2EffectResourceMap) */\r\n resources = new Map();\r\n\r\n /** uavs (Tr2EffectResourceMap) */\r\n uavs = new Map();\r\n\r\n /** samplers (Tr2SamplerSetupMap) */\r\n samplers = new Map();\r\n\r\n /** m_shader (unsigned) */\r\n shader = 0xffffffff;\r\n\r\n /** constants (Tr2EffectConstantVector) */\r\n constants = [];\r\n\r\n /** m_constantValueSize (unsigned) */\r\n constantValueSize = 0;\r\n\r\n /** constantValues (char[SHADER_CONSTANTS_MAX]) */\r\n constantValues = new Uint8Array(0);\r\n\r\n /** signature (Tr2ShaderSignatureAL) */\r\n signature = null;\r\n\r\n /** annotation (Tr2EffectParameterAnnotationMap) */\r\n annotation = [];\r\n\r\n /** Exact source program metadata and owned bytes, before backend realization. */\r\n sourceProgram = null;\r\n\r\n // Ported from CarbonEngine (MIT, (c) 2026 CCP Games) - https://github.com/carbonengine/trinity\r\n // trinity/Shader/Tr2Effect.cpp:1799-1821 (the sizing loop and its assertion)\r\n //\r\n // Carbon's comment at the site is the whole rule: \"Figure out how large the\r\n // constant buffer has to be. This has to be done even if the constant isn't\r\n // set, as the shader may still sample it and expect to get some kind of\r\n // default (usually zero).\" So EVERY constant participates, not only the ones\r\n // an effect binds a parameter to.\r\n //\r\n // THIS IS NOT `constantValueSize`, AND THE DIFFERENCE IS EASY TO MISS.\r\n // `constantValueSize` is the length of the authored DEFAULT blob, which\r\n // Carbon separately grows to cover autoregister sampler-index constants\r\n // (Tr2EffectDescription.cpp:629-632). Carbon asserts\r\n // `constantSize >= constantDefaultValueSize` precisely because the two are\r\n // different numbers and the defaults are a PREFIX of the buffer. An effect\r\n // that authors defaults for only some of its constants makes them differ, so\r\n // using the default size as the buffer size is right until it silently is\r\n // not.\r\n //\r\n // It lives here rather than in a consumer because it is arithmetic over this\r\n // object's own constants and gives every backend the same answer. A backend\r\n // then applies its own alignment on top - WebGPU's uniform binding alignment,\r\n // std140 for a WebGL2 block - and that padding is the backend's, not this.\r\n // Decision 4 of the engine backends plan names the alternative as a defect\r\n // worth declining to inherit: Carbon replicates its draw-argument arithmetic\r\n // across ten call sites, and this would replicate the same way once a second\r\n // engine exists.\r\n\r\n /**\r\n * The byte size a constant buffer must have to hold every declared constant.\r\n *\r\n * Always at least `constantValueSize`, because the authored defaults occupy\r\n * the start of the same buffer.\r\n */\r\n GetConstantBufferSize()\r\n {\r\n let size = 0;\r\n\r\n for (const constant of this.constants)\r\n {\r\n size = Math.max(size, (constant?.offset ?? 0) + (constant?.size ?? 0));\r\n }\r\n\r\n return Math.max(size, this.constantValueSize);\r\n }\r\n\r\n /**\r\n * Construct one canonical stage input from JS/JSON model values.\r\n *\r\n * @param {object} values Canonical model values.\r\n * @param {object} options CjsModel import options.\r\n * @returns {Tr2EffectStageInput} Hydrated stage input.\r\n */\r\n static from(values = {}, options = {})\r\n {\r\n let normalized = values;\r\n const maps = new Map();\r\n for (const [ field, Constructor ] of [\r\n [ \"resources\", Tr2EffectResource ],\r\n [ \"uavs\", Tr2EffectResource ],\r\n [ \"samplers\", Tr2SamplerSetup ]\r\n ])\r\n {\r\n if (values && Object.hasOwn(values, field))\r\n {\r\n normalized = normalized === values ? { ...values } : normalized;\r\n normalized[field] = this.readCanonicalRegisterMap(\r\n values[field],\r\n Constructor,\r\n options,\r\n field\r\n );\r\n maps.set(field, normalized[field]);\r\n }\r\n }\r\n const stage = super.from(normalized, options);\r\n for (const [ field, value ] of maps)\r\n {\r\n stage[field] = value;\r\n }\r\n return stage;\r\n }\r\n\r\n /**\r\n * Hydrate one canonical stage input from a decoded Carbon binary record.\r\n *\r\n * @param {object} record Decoded Carbon stage record.\r\n * @returns {Tr2EffectStageInput} Hydrated canonical stage input.\r\n */\r\n static fromCarbonBinary(record)\r\n {\r\n if (!isPlainObject(record))\r\n {\r\n throw new TypeError(\"Carbon effect stage record must be an object\");\r\n }\r\n\r\n const input = this.fromCarbonBinaryInput(record, record.type);\r\n input.signature.pipelineInputCount = record.pipelineInputs.length;\r\n input.signature.pipelineInputs = record.pipelineInputs.map(entry => ({\r\n usage: entry.usage,\r\n registerIndex: entry.registerIndex,\r\n usageIndex: entry.usageIndex,\r\n usedMask: entry.usedMask,\r\n type: entry.type,\r\n dimension: entry.dimension\r\n }));\r\n input.signature.threadGroupSize = {\r\n x: record.threadGroupSize[0],\r\n y: record.threadGroupSize[1],\r\n z: record.threadGroupSize[2]\r\n };\r\n input.sourceProgram = {\r\n kind: \"stage\",\r\n bytes: copyBytes(recordBytes(record.shaderData)),\r\n shaderSize: record.shaderData.size,\r\n // Meaningful only at size zero, where the writer passes the word through\r\n // rather than interning. At any other size it is a live arena offset that\r\n // belongs to the container it was read from, so it is not retained.\r\n unsetOffset: unsetOffsetOf(record.shaderData)\r\n };\r\n return input;\r\n }\r\n\r\n /**\r\n * Build one stage input from a Carbon v15 `StageData` block.\r\n *\r\n * A raytracing library's global and local inputs are the same block without a\r\n * stage wrapper — no stage type, no pipeline inputs, no thread group, no\r\n * program of their own — so this is the half both callers share and\r\n * `fromCarbonBinary` is the stage-only remainder layered on top.\r\n *\r\n * Carbon writes textures, samplers and UAVs in ascending register order because\r\n * they are `std::map`s, and they are re-keyed by register here rather than by\r\n * position, so the map is authoritative and the record's order is not load\r\n * bearing.\r\n *\r\n * @param {object} record Carbon stage-data record.\r\n * @param {number} [stageType] Stage index, or -1 for a library input.\r\n * @returns {Tr2EffectStageInput} Reflected stage input.\r\n */\r\n static fromCarbonBinaryInput(record, stageType = -1)\r\n {\r\n if (!isPlainObject(record))\r\n {\r\n throw new TypeError(\"Carbon effect stage-data record must be an object\");\r\n }\r\n\r\n const constantValues = copyBytes(recordBytes(record.defaultValues));\r\n\r\n const input = new this();\r\n input.stageType = stageType;\r\n input.exists = true;\r\n input.constants = record.constants.map(\r\n entry => Tr2EffectConstant.fromCarbonBinary(entry)\r\n );\r\n input.resources = this.readCarbonBinaryResourceMap(record.textures);\r\n input.uavs = this.readCarbonBinaryResourceMap(record.uavs);\r\n input.samplers = this.readCarbonBinarySamplerMap(record.samplers);\r\n input.constantValueSize = constantValues.byteLength;\r\n input.constantValues = constantValues;\r\n input.constantValuesUnsetOffset = unsetOffsetOf(record.defaultValues);\r\n input.annotation = record.annotations.map(\r\n entry => Tr2EffectParameterAnnotation.fromCarbonBinary(entry)\r\n );\r\n input.signature = {\r\n pipelineInputCount: 0,\r\n pipelineInputs: [],\r\n registerCount: record.registers.length,\r\n // Carbon stores one field its reader calls `arrayCount` and its writer\r\n // calls `registerCount`. Both names are carried forward from the single\r\n // stored value, because the write direction refuses to emit a record whose\r\n // two names disagree.\r\n registers: record.registers.map(entry => ({\r\n registerType: entry.registerType,\r\n registerIndex: entry.registerIndex,\r\n arrayCount: entry.registerCount,\r\n registerCount: entry.registerCount,\r\n registerSpace: entry.registerSpace\r\n })),\r\n staticSamplerCount: record.staticSamplers.length,\r\n staticSamplers: record.staticSamplers.map(entry => ({\r\n registerIndex: entry.registerIndex,\r\n registerSpace: entry.registerSpace,\r\n descriptor: {\r\n comparison: !!entry.comparison,\r\n minFilter: entry.minFilter,\r\n magFilter: entry.magFilter,\r\n mipFilter: entry.mipFilter,\r\n addressU: entry.addressU,\r\n addressV: entry.addressV,\r\n addressW: entry.addressW,\r\n mipLODBiasRaw: recordRawBits(entry.mipLODBias),\r\n maxAnisotropy: entry.maxAnisotropy,\r\n comparisonFunc: entry.comparisonFunc,\r\n // A static sampler's border colour is a one-byte enum, not four\r\n // floats. Sharing the dynamic sampler's mapping here would silently\r\n // reinterpret it.\r\n borderColor: entry.borderColor,\r\n minLODRaw: recordRawBits(entry.minLOD),\r\n maxLODRaw: recordRawBits(entry.maxLOD)\r\n }\r\n })),\r\n threadGroupSize: { x: 0, y: 0, z: 0 }\r\n };\r\n input.sourceProgram = null;\r\n return input;\r\n }\r\n\r\n /**\r\n * Emit this stage as a Carbon v15 stage record.\r\n *\r\n * @returns {object} Carbon stage record.\r\n */\r\n toCarbonBinary()\r\n {\r\n const signature = this.signature ?? {};\r\n const program = this.sourceProgram ?? {};\r\n return {\r\n type: this.stageType,\r\n shaderData: toRecordBlob(\r\n program.bytes,\r\n program.shaderSize,\r\n program.unsetOffset\r\n ),\r\n threadGroupSize: [\r\n signature.threadGroupSize?.x ?? 0,\r\n signature.threadGroupSize?.y ?? 0,\r\n signature.threadGroupSize?.z ?? 0\r\n ],\r\n pipelineInputs: (signature.pipelineInputs ?? []).map(entry => ({\r\n usage: entry.usage,\r\n registerIndex: entry.registerIndex,\r\n usageIndex: entry.usageIndex,\r\n usedMask: entry.usedMask,\r\n type: entry.type,\r\n dimension: entry.dimension\r\n })),\r\n ...this.toCarbonBinaryInput()\r\n };\r\n }\r\n\r\n /**\r\n * Emit this input as a Carbon v15 `StageData` block.\r\n *\r\n * Carbon holds textures, samplers, UAVs and render states in `std::map`s and\r\n * writes them in key order, and it sorts annotation names by `strcmp` before\r\n * writing. Our maps are keyed but not ordered, so every collection is sorted\r\n * explicitly here rather than trusting insertion order — the reader is\r\n * indifferent, but the bytes are not, and a container that disagrees with\r\n * Carbon's ordering is not the file Carbon would have written.\r\n *\r\n * @returns {object} Carbon stage-data record.\r\n */\r\n toCarbonBinaryInput()\r\n {\r\n const byRegister = (left, right) => left.registerIndex - right.registerIndex;\r\n const signature = this.signature ?? {};\r\n return {\r\n registers: (signature.registers ?? []).map(entry => ({\r\n registerType: entry.registerType,\r\n registerIndex: entry.registerIndex,\r\n registerCount: entry.registerCount,\r\n registerSpace: entry.registerSpace\r\n })),\r\n staticSamplers: (signature.staticSamplers ?? []).map(entry =>\r\n {\r\n const descriptor = entry.descriptor ?? {};\r\n return {\r\n registerIndex: entry.registerIndex,\r\n registerSpace: entry.registerSpace,\r\n comparison: descriptor.comparison ? 1 : 0,\r\n minFilter: descriptor.minFilter,\r\n magFilter: descriptor.magFilter,\r\n mipFilter: descriptor.mipFilter,\r\n addressU: descriptor.addressU,\r\n addressV: descriptor.addressV,\r\n addressW: descriptor.addressW,\r\n mipLODBias: toRecordFloat(descriptor.mipLODBiasRaw),\r\n maxAnisotropy: descriptor.maxAnisotropy,\r\n comparisonFunc: descriptor.comparisonFunc,\r\n // One byte here, four floats on a dynamic sampler.\r\n borderColor: descriptor.borderColor,\r\n minLOD: toRecordFloat(descriptor.minLODRaw),\r\n maxLOD: toRecordFloat(descriptor.maxLODRaw)\r\n };\r\n }),\r\n constants: this.constants.map(constant => constant.toCarbonBinary()),\r\n defaultValues: toRecordBlob(\r\n this.constantValues,\r\n this.constantValueSize,\r\n this.constantValuesUnsetOffset\r\n ),\r\n textures: Array.from(this.resources, ([ register, resource ]) =>\r\n resource.toCarbonBinary(register)).sort(byRegister),\r\n samplers: Array.from(this.samplers, ([ register, sampler ]) =>\r\n sampler.toCarbonBinary(register)).sort(byRegister),\r\n uavs: Array.from(this.uavs, ([ register, uav ]) =>\r\n uav.toCarbonBinary(register, true)).sort(byRegister),\r\n annotations: this.annotation\r\n .map(entry => entry.toCarbonBinary())\r\n .sort((left, right) => compareUtf8(left.name.value, right.name.value))\r\n };\r\n }\r\n\r\n /** Build one register-indexed resource map from Carbon texture or UAV records. */\r\n static readCarbonBinaryResourceMap(records)\r\n {\r\n const result = new Map();\r\n for (const record of records)\r\n {\r\n if (result.has(record.registerIndex))\r\n {\r\n throw new Error(\r\n `Carbon effect resource register ${record.registerIndex} is duplicated`\r\n );\r\n }\r\n result.set(\r\n record.registerIndex,\r\n Tr2EffectResource.fromCarbonBinary(record)\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n /** Build one register-indexed sampler map from Carbon sampler records. */\r\n static readCarbonBinarySamplerMap(records)\r\n {\r\n const result = new Map();\r\n for (const record of records)\r\n {\r\n if (result.has(record.registerIndex))\r\n {\r\n throw new Error(\r\n `Carbon effect sampler register ${record.registerIndex} is duplicated`\r\n );\r\n }\r\n result.set(\r\n record.registerIndex,\r\n Tr2SamplerSetup.fromCarbonBinary(record)\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Create one explicit absent stage slot.\r\n *\r\n * @param {number} stageType Stage index.\r\n * @returns {Tr2EffectStageInput} Empty stage input.\r\n */\r\n static createEmpty(stageType)\r\n {\r\n const stage = new this();\r\n stage.stageType = requireShaderStageType(stageType);\r\n return stage;\r\n }\r\n\r\n /**\r\n * Normalize one register-indexed collection into its canonical typed map.\r\n *\r\n * @param {Map|object} values Register-indexed source values.\r\n * @param {Function} Constructor Entry constructor exposing `from`.\r\n * @param {object} options Hydration options passed to entry construction.\r\n * @param {string} field Diagnostic field name.\r\n * @returns {Map<number, *>} Canonical register map.\r\n */\r\n static readCanonicalRegisterMap(values, Constructor, options, field)\r\n {\r\n const entries = values instanceof Map\r\n ? values\r\n : Object.entries(values ?? {});\r\n const result = new Map();\r\n for (const [ key, value ] of entries)\r\n {\r\n const registerIndex = Number(key);\r\n if (!isUint32(registerIndex))\r\n {\r\n throw new RangeError(\r\n `Effect ${field} register index must fit uint32`\r\n );\r\n }\r\n if (result.has(registerIndex))\r\n {\r\n throw new Error(\r\n `Effect ${field} register ${registerIndex} is duplicated`\r\n );\r\n }\r\n result.set(\r\n registerIndex,\r\n value instanceof Constructor\r\n ? value\r\n : Constructor.from(value, options)\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n}\r\n\r\n// Declared imperatively rather than with decorators, so this module stays\r\n// plain ESM that loads from source without a transform. The decorator\r\n// expressions are reused verbatim, so the registered metadata is identical.\r\n// Statics belong in `methods`: decorateMethod targets the prototype and\r\n// would register a static as an instance field.\r\nCjsSchema.define(Tr2EffectStageInput, {\r\n className: \"Tr2EffectStageInput\",\r\n family: \"shader\",\r\n fields: {\r\n stageType: [ impl.adapted, impl.reason(\"The source format identifies stage inputs by array index; the device-free graph retains the index explicitly for serialization and engine adapters.\"), type.int32 ],\r\n exists: type.boolean,\r\n resources: type.map(\"Tr2EffectResource\"),\r\n uavs: type.map(\"Tr2EffectResource\"),\r\n samplers: type.map(\"Tr2SamplerSetup\"),\r\n shader: type.uint32,\r\n constants: type.list(\"Tr2EffectConstant\"),\r\n constantValueSize: type.uint32,\r\n constantValues: type.typedArray(\"Uint8Array\"),\r\n constantValuesUnsetOffset: [ impl.custom, impl.reason(\"A zero-size blob's offset word is passed through rather than interned, and the shipped corpus does not always set it to the null sentinel; the graph retains it so a body re-emits as the file that produced it.\"), type.uint32 ],\r\n signature: type.rawStruct(\"Tr2ShaderSignatureAL\"),\r\n annotation: type.list(\"Tr2EffectParameterAnnotation\"),\r\n sourceProgram: [ impl.adapted, impl.reason(\"Carbon replaces source program data with renderer handles while reading; the device-free resource graph must retain the portable source program for later engine realization.\"), type.rawStruct(\"CjsEffectSourceProgram\") ]\r\n }\r\n});\r\n"],"names":["unsetOffsetOf","ref","size","offset","Tr2EffectStageInput","CjsModel","stageType","exists","resources","Map","uavs","samplers","shader","constants","constantValueSize","constantValues","Uint8Array","signature","annotation","sourceProgram","GetConstantBufferSize","constant","Math","max","from","values","options","normalized","maps","field","Constructor","Tr2EffectResource","Tr2SamplerSetup","Object","hasOwn","readCanonicalRegisterMap","set","stage","value","fromCarbonBinary","record","isPlainObject","TypeError","input","fromCarbonBinaryInput","type","pipelineInputCount","pipelineInputs","length","map","entry","usage","registerIndex","usageIndex","usedMask","dimension","threadGroupSize","x","y","z","kind","bytes","copyBytes","recordBytes","shaderData","shaderSize","unsetOffset","defaultValues","Tr2EffectConstant","readCarbonBinaryResourceMap","textures","readCarbonBinarySamplerMap","byteLength","constantValuesUnsetOffset","annotations","Tr2EffectParameterAnnotation","registerCount","registers","registerType","arrayCount","registerSpace","staticSamplerCount","staticSamplers","descriptor","comparison","minFilter","magFilter","mipFilter","addressU","addressV","addressW","mipLODBiasRaw","recordRawBits","mipLODBias","maxAnisotropy","comparisonFunc","borderColor","minLODRaw","minLOD","maxLODRaw","maxLOD","toCarbonBinary","program","toRecordBlob","toCarbonBinaryInput","byRegister","left","right","toRecordFloat","Array","register","resource","sort","sampler","uav","compareUtf8","name","records","result","has","Error","createEmpty","requireShaderStageType","entries","key","Number","isUint32","RangeError","CjsSchema","define","className","family","fields","impl","adapted","reason","int32","boolean","uint32","list","typedArray","custom","rawStruct"],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ # Format type resolution
2
+
3
+ Status: Evolving
4
+ Scope: `CjsFormat.resolveType`, `CjsResourceProbe`, and the formats that override them
5
+ Audience: Anyone adding a format, choosing a decode route, or debugging a mislabeled container
6
+ Summary: Separates what a container claims about itself from what a reader has evidence it can decode, and states how a verified resolution may and may not change a route.
7
+
8
+ ## Claims versus evidence
9
+
10
+ A container's header is a claim. `inspect()` and `isSupported()` report that
11
+ claim: they read the declaration and answer whether this format recognizes it.
12
+ That is the right answer almost always, and it is cheap.
13
+
14
+ `resolveType()` answers a different question — what the reader has *evidence*
15
+ it can actually decode. It performs one bounded asynchronous content check: a
16
+ magic number, a first frame or block, a setup header. It never decodes the
17
+ payload.
18
+
19
+ The distinction matters because a mislabeled container is indistinguishable
20
+ from a correct one until something looks at the content. Routing on the
21
+ declaration alone turns that into a decode failure much later, somewhere that
22
+ has forgotten what the file claimed to be.
23
+
24
+ ## The contract
25
+
26
+ `resolveType()` returns a `CjsResourceProbe`. The probe carries a persisted
27
+ `verified` boolean, and its `metadata` carries the evidence: what was
28
+ declared, what resolved, and whether those disagreed. `preferred` names the
29
+ resolved decode route.
30
+
31
+ Three rules govern what a probe may do:
32
+
33
+ - **A caller-forced emit always wins.** Resolution informs a default; it never
34
+ overrides an explicit request.
35
+ - **An unverified result never changes a route.** The base implementation
36
+ delegates to `isSupported()` and sets `verified` to false, so a format
37
+ without an override costs nothing and cannot silently redirect anything.
38
+ - **Opting in is per format.** Overriding is a decision made by a format that
39
+ has a cheap, meaningful content check — not a requirement on all of them.
40
+
41
+ That third rule is why this is a seam rather than a pipeline stage. The
42
+ zero-extra-work path is the default, and it stays free.
43
+
44
+ ## What a check may look like: wem
45
+
46
+ `CjsWemFormat` overrides it, and its shape is the model. The `fmt` tag is the
47
+ declaration. Each candidate codec gets one bounded **structural** check
48
+ against container facts — a Wwise Vorbis sidecar present with a positive
49
+ sample count; a PTADPCM frame layout satisfying the decoder's own guard with
50
+ block-aligned data; PCM with self-consistent block alignment and byte rate.
51
+ No audio is decoded in any of them.
52
+
53
+ The declared codec is validated first. Only when its check fails are the other
54
+ candidates tried, in order. The resolved codec maps to an emit — Wwise Vorbis
55
+ to `ogg`, PTADPCM and PCM to `pcm`, anything unresolved to `raw`.
56
+
57
+ A census of all 8,987 embedded wems in one EVE build found no mislabeled tag.
58
+ That is the point rather than a reason to drop the check: it converts a
59
+ corpus-wide assumption into a fact verified per file, and the cost of holding
60
+ that guarantee is one structural read.
61
+
62
+ ## Current limits
63
+
64
+ Resolution is available to callers but is **not yet wired into the resource
65
+ read path**. `CjsResMan` still selects a format by extension using the
66
+ synchronous `isSupported()` tie-break, so a mislabeled file routed through
67
+ ordinary resource acquisition is not corrected today. Consumers that need the
68
+ verified answer call `resolveType()` themselves.
69
+
70
+ Wem exposes `raw`, `ogg`, and `pcm` as distinct outputs, so a caller still
71
+ chooses a decoder. A single resolve-then-route output that hides the codec
72
+ choice is [planned](../roadmap.md), not present.
73
+
74
+ ## Related documentation
75
+
76
+ - [Resource lifecycle](resource-lifecycle.md) — how a resource is acquired,
77
+ prepared, and published.
78
+ - [Wwise formats](../formats/wwise.md) — the wem container these checks read.
79
+ - [Roadmap](../roadmap.md) — the unbuilt read-path integration.
@@ -72,6 +72,17 @@ Detailed pages: [Granny GR2 and GSF](gr2.md),
72
72
  history, retained snapshots, and donor licensing are recorded in
73
73
  [provenance.md](provenance.md).
74
74
 
75
+ `CjsPngFormat.inspect(bytes)` is the one-shot, decode-free PNG inspection
76
+ entry point. In addition to the header and bounded chunk summary, it exposes
77
+ the standard ancillary placement chunks when present:
78
+
79
+ - `offset: { x, y, unit }` from `oFFs`, with signed 32-bit coordinates; and
80
+ - `physicalPixelDimensions: { x, y, unit }` from `pHYs`, with unsigned 32-bit
81
+ values.
82
+
83
+ These are raw PNG facts. Runtime-resource does not assign character-atlas or
84
+ other domain semantics to their values.
85
+
75
86
  ## Black and Red reader boundary
76
87
 
77
88
  `CjsBlackReader` and `CjsRedReader` share `CjsBlueReader` as an output and
@@ -63,10 +63,17 @@ Equivalent read surfaces are derived from the one Carbon record tree:
63
63
  | `WGSL` | Program text and layouts read from stage records and backend blocks |
64
64
  | `WGSB` | A body-set view derived across distinct stored bodies |
65
65
 
66
- `Read(..., { emit: "json" })` returns these compatibility views as plain data.
67
- They are not independent stored documents and carry no cross-document digests.
68
- `Read(..., { emit: "raw" })` returns the internal `CarbonWebgpuContainer` reader.
69
- There is no `chunks` array and no generic `Build(chunks)` API.
66
+ `Read` returns these derived views as plain data. They are not independent stored
67
+ documents and carry no cross-document digests. There is no `chunks` array and no
68
+ generic `Build(chunks)` API.
69
+
70
+ There is exactly one emit, as there is for WebGL, and the document it returns is
71
+ complete: alongside the views above it carries `permutationGraph` and
72
+ `backendBodySet`, the latter being every translated body joined to its shared
73
+ translation units. A second `raw` emit used to hand back the internal
74
+ `CarbonWebgpuContainer` because the former chunk package could not express the
75
+ body set in JSON. It is removed. The container is internal, and consumers read
76
+ the document rather than binding to a reader object.
70
77
 
71
78
  ## Building
72
79
 
@@ -75,7 +75,7 @@ Callers establish identity through the resource path that supplied the bytes.
75
75
 
76
76
  | Option | Meaning |
77
77
  | --- | --- |
78
- | `emit` | `"json"` by default or `"raw"` for the internal container reader. |
78
+ | `emit` | `"json"`, the only accepted value. Any other value is a `TypeError`. |
79
79
  | `source` | Caller-owned diagnostic label; it is never opened. |
80
80
  | `decodeInstructions` | Includes decoded instruction and IR detail during analysis. |
81
81
  | `permutation` | Exact `NAME=VALUE` assertions for `AnalyzeEffect` and `BuildEffect`; ignored by current `Read` and `Inspect`. |
@@ -85,8 +85,9 @@ Callers establish identity through the resource path that supplied the bytes.
85
85
  Class registrations are validated and stored for forward compatibility.
86
86
  Current JSON reads return plain data rather than hydrated package classes.
87
87
 
88
- Raw output is an internal reader over the same bytes. It is not a second wire
89
- format and should not be persisted.
88
+ There is one emit. The document it returns carries every view a consumer needs,
89
+ including `permutationGraph` and the complete `backendBodySet`, so there is no
90
+ second read mode to choose and no reader object to hold.
90
91
 
91
92
  ## Read result
92
93
 
@@ -174,9 +175,9 @@ coalescing uses version 3 and carries an explicit transform recipe.
174
175
 
175
176
  ## Static metadata
176
177
 
177
- The class exposes `OUTPUT_JSON`, `OUTPUT_RAW`, `CLASS_KEYS`, `type`,
178
- `mediaTypes`, `inputTypes`, `outputTypes`, `debugOutputTypes`,
179
- `implementationStatus`, `format`, `analysisFormat`, and `packageVersion`.
178
+ The class exposes `OUTPUT_JSON`, `CLASS_KEYS`, `type`, `mediaTypes`,
179
+ `inputTypes`, `outputTypes`, `implementationStatus`, `format`, `analysisFormat`,
180
+ and `packageVersion`. There is no `OUTPUT_RAW` and no `debugOutputTypes`.
180
181
 
181
182
  ## Errors
182
183
 
@@ -140,6 +140,31 @@ media index-to-source mappings, RTPC curves, state values, and initial plug-in
140
140
  property values. Opaque parameter bytes are intentional: a consumer must
141
141
  qualify each plug-in's DSP behavior before interpreting them.
142
142
 
143
+ ## Two facts about the pin and the container
144
+
145
+ **The version-150 pin has a horizon.** The typed decoding above is deliberately
146
+ bound to bank generator version 150, which is what current EVE builds ship. The
147
+ Wwise SDK that CarbonEngine itself pins is `2025.1.5.9095`, a generation whose
148
+ authoring tools emit a substantially later bank version. So the pin is expected
149
+ to be broken by a toolchain upgrade on the producing side rather than by
150
+ anything here, and the failure will look like whole-body rejection rather than
151
+ misreading: unknown or other-version bodies fall back to shallow action
152
+ type/target with `action: null`, which is the designed behavior. Treat a sudden
153
+ rise in `action: null` across a new build as a version bump, not corruption.
154
+
155
+ **EVE wems carry a chunk that is not part of Wwise's own layout.** Observed
156
+ between `fmt ` and `data`: a 24-byte `hash` chunk holding a 16-byte digest. The
157
+ engine never reads it, and its derivation is unverified — it is not the resource
158
+ index's whole-file md5. The repacker tolerates it structurally rather than by
159
+ name: the chunk walk records only `fmt `, `vorb`, `data`, and `smpl` and
160
+ advances past everything else, so an unrecognized chunk is skipped wherever it
161
+ appears. That is why the chunk is safe to ignore, and why it must stay safe —
162
+ a walk that assumed a fixed chunk order or a known-id whitelist would break on
163
+ these files.
164
+
165
+ Both observations are pinned to a 2026-07 corpus reading. Re-verify against a
166
+ current build before relying on either.
167
+
143
168
  ## Related documentation
144
169
 
145
170
  - [Format subpaths](README.md)