@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.
- package/dist/format/CjsFormat.js +84 -83
- package/dist/format/CjsFormat.js.map +1 -1
- package/dist/format/CjsResourceProbe.js +87 -86
- package/dist/format/CjsResourceProbe.js.map +1 -1
- package/dist/format/carbonEffect/backendEngineId.js +98 -0
- package/dist/format/carbonEffect/backendEngineId.js.map +1 -0
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js +24 -23
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectResourceTransform.js +1 -1
- package/dist/format/carbonEffect/carbonEffectResourceTransform.js.map +1 -1
- package/dist/format/effect/effectPermutationGraph.js +46 -29
- package/dist/format/effect/effectPermutationGraph.js.map +1 -1
- package/dist/format/index.js +1 -1
- package/dist/formats/hlsl/core/detailMapFamily.js +1 -1
- package/dist/formats/hlsl/core/detailMapFamily.js.map +1 -1
- package/dist/formats/hlsl/core/localLightFamily.js +1 -1
- package/dist/formats/hlsl/core/localLightFamily.js.map +1 -1
- package/dist/formats/png/core/helpers.js +27 -8
- package/dist/formats/png/core/helpers.js.map +1 -1
- package/dist/formats/webgl/core/effectPackage.js +143 -56
- package/dist/formats/webgl/core/effectPackage.js.map +1 -1
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +799 -456
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
- package/dist/formats/webgl/core/glslBackendBlock.js +74 -30
- package/dist/formats/webgl/core/glslBackendBlock.js.map +1 -1
- package/dist/formats/webgl/core/glslBackendBodySet.js +0 -1
- package/dist/formats/webgl/core/glslBackendBodySet.js.map +1 -1
- package/dist/formats/webgl/core/helpers.js +53 -53
- package/dist/formats/webgl/core/helpers.js.map +1 -1
- package/dist/formats/webgl/core/readGlslEffectContainer.js +82 -67
- package/dist/formats/webgl/core/readGlslEffectContainer.js.map +1 -1
- package/dist/formats/webgpu/CjsWebgpuFormat.js +161 -163
- package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
- package/dist/formats/webgpu/core/carbonWebgpu/CarbonWebgpuContainer.js +10 -1
- package/dist/formats/webgpu/core/carbonWebgpu/CarbonWebgpuContainer.js.map +1 -1
- package/dist/formats/webgpu/core/effectBackendBodySet.js +21 -22
- package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
- package/dist/formats/webgpu/core/helpers.js +111 -99
- package/dist/formats/webgpu/core/helpers.js.map +1 -1
- package/dist/formats/webgpu/core/packageEffect.js +30 -32
- package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
- package/dist/formats/wem/CjsWemFormat.js +121 -121
- package/dist/formats/wem/CjsWemFormat.js.map +1 -1
- package/dist/formats/wem/core/resolve.js +8 -8
- package/dist/formats/wem/core/resolve.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js +102 -60
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
- package/docs/concepts/format-type-resolution.md +79 -0
- package/docs/formats/README.md +11 -0
- package/docs/formats/webgpu/formats/carbon-webgpu.md +11 -4
- package/docs/formats/webgpu/reference/api.md +7 -6
- package/docs/formats/wwise.md +25 -0
- package/docs/roadmap.md +19 -0
- package/package.json +2 -2
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
import { sha256Bytes } from './sha256.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* The source permutation topology: which permutations exist, and which of them
|
|
5
|
+
* share one body.
|
|
6
|
+
*
|
|
7
|
+
* This module used to model that as the `PGRF` **chunk** - it exported the tag,
|
|
8
|
+
* and every error it raised named it. There are no chunks. A `.carbonwebgpu` or
|
|
9
|
+
* `.carbonwebgl` file is one Carbon v15 record container, and the graph the
|
|
10
|
+
* container publishes is a *view* over the header's own permutation records and
|
|
11
|
+
* offset table, not a stored document beside them. The chunk vocabulary outlived
|
|
12
|
+
* the reader beneath it by weeks precisely because nothing was broken: packages
|
|
13
|
+
* built, ccpwgl rendered, and the only cost was that every error message named a
|
|
14
|
+
* container the file no longer had.
|
|
15
|
+
*
|
|
16
|
+
* The graph is still built here, from the decoded effect resource, because that
|
|
17
|
+
* is where the source topology is known. What is gone is the claim that it is
|
|
18
|
+
* stored anywhere.
|
|
19
|
+
*/
|
|
20
|
+
|
|
3
21
|
const EFFECT_PERMUTATION_GRAPH_FORMAT = "CJS_EFFECT_PERMUTATION_GRAPH";
|
|
4
22
|
const EFFECT_PERMUTATION_GRAPH_VERSION = 1;
|
|
5
|
-
const EFFECT_PERMUTATION_GRAPH_CHUNK = "PGRF";
|
|
6
23
|
const SHA256 = /^[0-9a-f]{64}$/u;
|
|
7
24
|
const UINT8_MAX = 0xff;
|
|
8
25
|
const UINT32_MAX = 0xffffffff;
|
|
9
26
|
const MAX_EFFECT_PERMUTATIONS = 0x10000;
|
|
10
27
|
|
|
11
|
-
/**
|
|
12
|
-
* Build a complete source permutation topology without claiming that every
|
|
13
|
-
* body has portable reflection or backend programs.
|
|
14
|
-
*
|
|
15
|
-
* @param {object} effectRes Raw format-hlsl effect resource.
|
|
16
|
-
* @returns {object} JSON-safe permutation graph.
|
|
28
|
+
/**
|
|
29
|
+
* Build a complete source permutation topology without claiming that every
|
|
30
|
+
* body has portable reflection or backend programs.
|
|
31
|
+
*
|
|
32
|
+
* @param {object} effectRes Raw format-hlsl effect resource.
|
|
33
|
+
* @returns {object} JSON-safe permutation graph.
|
|
17
34
|
*/
|
|
18
35
|
function buildEffectPermutationGraph(effectRes) {
|
|
19
36
|
if (!effectRes || typeof effectRes !== "object") {
|
|
@@ -83,32 +100,32 @@ function buildEffectPermutationGraph(effectRes) {
|
|
|
83
100
|
return graph;
|
|
84
101
|
}
|
|
85
102
|
|
|
86
|
-
/**
|
|
87
|
-
* Validate a source permutation graph independently of the original effect
|
|
88
|
-
* bytes.
|
|
89
|
-
*
|
|
90
|
-
* @param {object} graph Candidate graph.
|
|
91
|
-
* @param {object} [options] Optional source-envelope limits.
|
|
92
|
-
* @param {number} [options.sourceByteLength] Exact enclosing source byte length.
|
|
93
|
-
* @returns {{permutationCount:number,uniqueBodyCount:number}} Validated counts.
|
|
103
|
+
/**
|
|
104
|
+
* Validate a source permutation graph independently of the original effect
|
|
105
|
+
* bytes.
|
|
106
|
+
*
|
|
107
|
+
* @param {object} graph Candidate graph.
|
|
108
|
+
* @param {object} [options] Optional source-envelope limits.
|
|
109
|
+
* @param {number} [options.sourceByteLength] Exact enclosing source byte length.
|
|
110
|
+
* @returns {{permutationCount:number,uniqueBodyCount:number}} Validated counts.
|
|
94
111
|
*/
|
|
95
112
|
function validateEffectPermutationGraph(graph, options = {}) {
|
|
96
113
|
if (!graph || typeof graph !== "object" || Array.isArray(graph) || graph.format !== EFFECT_PERMUTATION_GRAPH_FORMAT || graph.formatVersion !== EFFECT_PERMUTATION_GRAPH_VERSION || !graph.coverage || typeof graph.coverage !== "object" || Array.isArray(graph.coverage) || graph.coverage.permutations !== "complete" || graph.coverage.bodies !== "identity-only" || graph.coverage.reflection !== "absent") {
|
|
97
|
-
throw new Error("
|
|
114
|
+
throw new Error("Effect permutation graph schema or coverage is unsupported");
|
|
98
115
|
}
|
|
99
116
|
const axes = validateGraphAxes(graph.axes);
|
|
100
117
|
const permutationCount = permutationProduct(axes);
|
|
101
118
|
if (!Array.isArray(graph.variants) || graph.variants.length !== permutationCount) {
|
|
102
|
-
throw new Error("
|
|
119
|
+
throw new Error("Effect permutation graph must contain one variant per Cartesian permutation");
|
|
103
120
|
}
|
|
104
121
|
if (!Array.isArray(graph.bodies) || !graph.bodies.length || graph.bodies.length > graph.variants.length) {
|
|
105
|
-
throw new Error("
|
|
122
|
+
throw new Error("Effect permutation graph bodies are malformed");
|
|
106
123
|
}
|
|
107
124
|
const bodies = new Map();
|
|
108
125
|
const bodyDigests = new Set();
|
|
109
126
|
for (const [bodyIndex, body] of graph.bodies.entries()) {
|
|
110
127
|
if (!body || typeof body !== "object" || Array.isArray(body) || typeof body.key !== "string" || !body.key || body.key !== body.key.trim() || !Number.isSafeInteger(body.byteLength) || body.byteLength < 1 || body.byteLength > UINT32_MAX || typeof body.sha256 !== "string" || !SHA256.test(body.sha256) || bodies.has(body.key) || bodyDigests.has(body.sha256)) {
|
|
111
|
-
throw new Error(`
|
|
128
|
+
throw new Error(`Effect permutation graph body ${bodyIndex} is malformed or duplicated`);
|
|
112
129
|
}
|
|
113
130
|
bodyDigests.add(body.sha256);
|
|
114
131
|
bodies.set(body.key, {
|
|
@@ -121,26 +138,26 @@ function validateEffectPermutationGraph(graph, options = {}) {
|
|
|
121
138
|
for (const [permutationIndex, variant] of graph.variants.entries()) {
|
|
122
139
|
const expectedOptionIndices = decodeOptionIndices(permutationIndex, axes);
|
|
123
140
|
if (!variant || typeof variant !== "object" || Array.isArray(variant) || variant.permutationIndex !== permutationIndex || !Array.isArray(variant.optionIndices) || variant.optionIndices.length !== expectedOptionIndices.length || variant.optionIndices.some((value, index) => value !== expectedOptionIndices[index]) || typeof variant.bodyKey !== "string" || !bodies.has(variant.bodyKey)) {
|
|
124
|
-
throw new Error(`
|
|
141
|
+
throw new Error(`Effect permutation graph variant ${permutationIndex} is malformed`);
|
|
125
142
|
}
|
|
126
143
|
const sourceRecord = validateGraphSourceRecord(variant.sourceRecord, permutationIndex, options.sourceByteLength);
|
|
127
144
|
const body = bodies.get(variant.bodyKey);
|
|
128
145
|
if (sourceRecord.byteLength !== body.byteLength) {
|
|
129
|
-
throw new Error(`
|
|
146
|
+
throw new Error(`Effect permutation graph variant ${permutationIndex} body length disagrees`);
|
|
130
147
|
}
|
|
131
148
|
const recordKey = `${sourceRecord.offset}:${sourceRecord.byteLength}`;
|
|
132
149
|
const existingBodyKey = bodyKeyBySourceRecord.get(recordKey);
|
|
133
150
|
if (existingBodyKey && existingBodyKey !== variant.bodyKey) {
|
|
134
|
-
throw new Error(`
|
|
151
|
+
throw new Error(`Effect permutation graph source record ${recordKey} maps to multiple bodies`);
|
|
135
152
|
}
|
|
136
153
|
bodyKeyBySourceRecord.set(recordKey, variant.bodyKey);
|
|
137
154
|
sourceRecords.push(sourceRecord);
|
|
138
155
|
body.references += 1;
|
|
139
156
|
}
|
|
140
|
-
validateDisjointSourceRecords(sourceRecords, "
|
|
157
|
+
validateDisjointSourceRecords(sourceRecords, "Effect permutation graph source body records partially overlap");
|
|
141
158
|
for (const [bodyKey, body] of bodies) {
|
|
142
159
|
if (!body.references) {
|
|
143
|
-
throw new Error(`
|
|
160
|
+
throw new Error(`Effect permutation graph body ${bodyKey} is unreferenced`);
|
|
144
161
|
}
|
|
145
162
|
}
|
|
146
163
|
return Object.freeze({
|
|
@@ -177,18 +194,18 @@ function normalizeAxes(value) {
|
|
|
177
194
|
}
|
|
178
195
|
function validateGraphAxes(value) {
|
|
179
196
|
if (!Array.isArray(value) || value.length > UINT8_MAX) {
|
|
180
|
-
throw new Error("
|
|
197
|
+
throw new Error("Effect permutation graph axes must be an array");
|
|
181
198
|
}
|
|
182
199
|
const names = new Set();
|
|
183
200
|
return value.map((axis, index) => {
|
|
184
201
|
if (!axis || typeof axis !== "object" || Array.isArray(axis) || axis.index !== index || typeof axis.name !== "string" || !axis.name || axis.name !== axis.name.trim() || names.has(axis.name) || !Array.isArray(axis.options) || !axis.options.length || axis.options.length > UINT8_MAX || !Number.isSafeInteger(axis.defaultOption) || axis.defaultOption < 0 || axis.defaultOption >= axis.options.length || typeof axis.description !== "string" || !Number.isSafeInteger(axis.type) || axis.type < 0 || axis.type > UINT8_MAX) {
|
|
185
|
-
throw new Error(`
|
|
202
|
+
throw new Error(`Effect permutation graph axis ${index} is malformed or duplicated`);
|
|
186
203
|
}
|
|
187
204
|
names.add(axis.name);
|
|
188
205
|
const options = new Set();
|
|
189
206
|
for (const option of axis.options) {
|
|
190
207
|
if (typeof option !== "string" || !option || option !== option.trim() || options.has(option)) {
|
|
191
|
-
throw new Error(`
|
|
208
|
+
throw new Error(`Effect permutation graph axis ${index} options are malformed`);
|
|
192
209
|
}
|
|
193
210
|
options.add(option);
|
|
194
211
|
}
|
|
@@ -227,7 +244,7 @@ function validateGraphSourceRecord(record, permutationIndex, sourceByteLength) {
|
|
|
227
244
|
const byteLength = record?.byteLength;
|
|
228
245
|
const end = offset + byteLength;
|
|
229
246
|
if (!record || typeof record !== "object" || Array.isArray(record) || !Number.isSafeInteger(offset) || offset < 0 || offset > UINT32_MAX || !Number.isSafeInteger(byteLength) || byteLength < 1 || byteLength > UINT32_MAX || !Number.isSafeInteger(end) || sourceByteLength !== undefined && (!Number.isSafeInteger(sourceByteLength) || sourceByteLength < 1 || end > sourceByteLength)) {
|
|
230
|
-
throw new Error(`
|
|
247
|
+
throw new Error(`Effect permutation graph variant ${permutationIndex} source record is malformed`);
|
|
231
248
|
}
|
|
232
249
|
return record;
|
|
233
250
|
}
|
|
@@ -253,5 +270,5 @@ function bytesEqual(left, right) {
|
|
|
253
270
|
return left.byteLength === right.byteLength && left.every((value, index) => value === right[index]);
|
|
254
271
|
}
|
|
255
272
|
|
|
256
|
-
export {
|
|
273
|
+
export { EFFECT_PERMUTATION_GRAPH_FORMAT, EFFECT_PERMUTATION_GRAPH_VERSION, buildEffectPermutationGraph, validateEffectPermutationGraph };
|
|
257
274
|
//# sourceMappingURL=effectPermutationGraph.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effectPermutationGraph.js","sources":["../../../../src/format/effect/effectPermutationGraph.js"],"sourcesContent":["import { sha256Bytes } from \"./sha256.js\";\n\nexport const EFFECT_PERMUTATION_GRAPH_FORMAT = \"CJS_EFFECT_PERMUTATION_GRAPH\";\nexport const EFFECT_PERMUTATION_GRAPH_VERSION = 1;\nexport const EFFECT_PERMUTATION_GRAPH_CHUNK = \"PGRF\";\n\nconst SHA256 = /^[0-9a-f]{64}$/u;\nconst UINT8_MAX = 0xff;\nconst UINT32_MAX = 0xffffffff;\nconst MAX_EFFECT_PERMUTATIONS = 0x10000;\n\n/**\n * Build a complete source permutation topology without claiming that every\n * body has portable reflection or backend programs.\n *\n * @param {object} effectRes Raw format-hlsl effect resource.\n * @returns {object} JSON-safe permutation graph.\n */\nexport function buildEffectPermutationGraph(effectRes)\n{\n if (!effectRes || typeof effectRes !== \"object\")\n {\n throw new TypeError(\"Effect permutation graph requires a decoded effect resource\");\n }\n\n const sourceBytes = effectRes.m_data;\n if (!(sourceBytes instanceof Uint8Array))\n {\n throw new TypeError(\"Effect permutation graph requires exact source bytes\");\n }\n\n const axes = normalizeAxes(effectRes.m_permutations);\n const permutationCount = permutationProduct(axes);\n const offsets = effectRes.m_offsets;\n if (!Array.isArray(offsets) || offsets.length !== permutationCount\n || effectRes.m_offsetCount !== offsets.length)\n {\n throw new Error(\n \"Effect permutation graph requires one source body record per permutation\"\n );\n }\n\n const sourceRecords = offsets.map((record, permutationIndex) =>\n normalizeSourceRecord(\n record,\n permutationIndex,\n sourceBytes.byteLength\n ));\n validateDisjointSourceRecords(\n sourceRecords,\n \"Effect permutation source body records partially overlap\"\n );\n\n const bodies = [];\n const bodyCandidatesByDigest = new Map();\n const bodyBySourceRecord = new Map();\n const variants = sourceRecords.map((sourceRecord, permutationIndex) =>\n {\n const sourceRecordKey = `${sourceRecord.offset}:${sourceRecord.byteLength}`;\n let body = bodyBySourceRecord.get(sourceRecordKey);\n if (!body)\n {\n const bodyBytes = sourceBytes.subarray(\n sourceRecord.offset,\n sourceRecord.offset + sourceRecord.byteLength\n );\n const digest = sha256Bytes(bodyBytes);\n body = (bodyCandidatesByDigest.get(digest) || [])\n .find((candidate) => bytesEqual(candidate.bytes, bodyBytes));\n if (!body && bodyCandidatesByDigest.has(digest))\n {\n throw new Error(\n \"Effect permutation graph body SHA-256 collision detected\"\n );\n }\n if (!body)\n {\n body = {\n bytes: bodyBytes,\n record: Object.freeze({\n key: `body${bodies.length}`,\n byteLength: bodyBytes.byteLength,\n sha256: digest\n })\n };\n bodyCandidatesByDigest.set(digest, [ body ]);\n bodies.push(body.record);\n }\n bodyBySourceRecord.set(sourceRecordKey, body);\n }\n\n return Object.freeze({\n permutationIndex,\n optionIndices: Object.freeze(decodeOptionIndices(\n permutationIndex,\n axes\n )),\n bodyKey: body.record.key,\n sourceRecord\n });\n });\n\n const graph = Object.freeze({\n format: EFFECT_PERMUTATION_GRAPH_FORMAT,\n formatVersion: EFFECT_PERMUTATION_GRAPH_VERSION,\n coverage: Object.freeze({\n permutations: \"complete\",\n bodies: \"identity-only\",\n reflection: \"absent\"\n }),\n axes: Object.freeze(axes),\n variants: Object.freeze(variants),\n bodies: Object.freeze(bodies)\n });\n\n validateEffectPermutationGraph(graph, {\n sourceByteLength: sourceBytes.byteLength\n });\n return graph;\n}\n\n/**\n * Validate a source permutation graph independently of the original effect\n * bytes.\n *\n * @param {object} graph Candidate graph.\n * @param {object} [options] Optional source-envelope limits.\n * @param {number} [options.sourceByteLength] Exact enclosing source byte length.\n * @returns {{permutationCount:number,uniqueBodyCount:number}} Validated counts.\n */\nexport function validateEffectPermutationGraph(graph, options = {})\n{\n if (!graph || typeof graph !== \"object\" || Array.isArray(graph)\n || graph.format !== EFFECT_PERMUTATION_GRAPH_FORMAT\n || graph.formatVersion !== EFFECT_PERMUTATION_GRAPH_VERSION\n || !graph.coverage || typeof graph.coverage !== \"object\"\n || Array.isArray(graph.coverage)\n || graph.coverage.permutations !== \"complete\"\n || graph.coverage.bodies !== \"identity-only\"\n || graph.coverage.reflection !== \"absent\")\n {\n throw new Error(\"PGRF schema or coverage is unsupported\");\n }\n\n const axes = validateGraphAxes(graph.axes);\n const permutationCount = permutationProduct(axes);\n if (!Array.isArray(graph.variants)\n || graph.variants.length !== permutationCount)\n {\n throw new Error(\n \"PGRF must contain one variant per Cartesian permutation\"\n );\n }\n if (!Array.isArray(graph.bodies)\n || !graph.bodies.length\n || graph.bodies.length > graph.variants.length)\n {\n throw new Error(\"PGRF bodies are malformed\");\n }\n\n const bodies = new Map();\n const bodyDigests = new Set();\n for (const [ bodyIndex, body ] of graph.bodies.entries())\n {\n if (!body || typeof body !== \"object\" || Array.isArray(body)\n || typeof body.key !== \"string\" || !body.key\n || body.key !== body.key.trim()\n || !Number.isSafeInteger(body.byteLength) || body.byteLength < 1\n || body.byteLength > UINT32_MAX\n || typeof body.sha256 !== \"string\" || !SHA256.test(body.sha256)\n || bodies.has(body.key)\n || bodyDigests.has(body.sha256))\n {\n throw new Error(`PGRF body ${bodyIndex} is malformed or duplicated`);\n }\n bodyDigests.add(body.sha256);\n bodies.set(body.key, {\n byteLength: body.byteLength,\n references: 0\n });\n }\n\n const bodyKeyBySourceRecord = new Map();\n const sourceRecords = [];\n for (const [ permutationIndex, variant ] of graph.variants.entries())\n {\n const expectedOptionIndices = decodeOptionIndices(permutationIndex, axes);\n if (!variant || typeof variant !== \"object\" || Array.isArray(variant)\n || variant.permutationIndex !== permutationIndex\n || !Array.isArray(variant.optionIndices)\n || variant.optionIndices.length !== expectedOptionIndices.length\n || variant.optionIndices.some((value, index) =>\n value !== expectedOptionIndices[index])\n || typeof variant.bodyKey !== \"string\"\n || !bodies.has(variant.bodyKey))\n {\n throw new Error(`PGRF variant ${permutationIndex} is malformed`);\n }\n\n const sourceRecord = validateGraphSourceRecord(\n variant.sourceRecord,\n permutationIndex,\n options.sourceByteLength\n );\n const body = bodies.get(variant.bodyKey);\n if (sourceRecord.byteLength !== body.byteLength)\n {\n throw new Error(\n `PGRF variant ${permutationIndex} body length disagrees`\n );\n }\n\n const recordKey = `${sourceRecord.offset}:${sourceRecord.byteLength}`;\n const existingBodyKey = bodyKeyBySourceRecord.get(recordKey);\n if (existingBodyKey && existingBodyKey !== variant.bodyKey)\n {\n throw new Error(\n `PGRF source record ${recordKey} maps to multiple bodies`\n );\n }\n bodyKeyBySourceRecord.set(recordKey, variant.bodyKey);\n sourceRecords.push(sourceRecord);\n body.references += 1;\n }\n\n validateDisjointSourceRecords(\n sourceRecords,\n \"PGRF source body records partially overlap\"\n );\n\n for (const [ bodyKey, body ] of bodies)\n {\n if (!body.references)\n {\n throw new Error(`PGRF body ${bodyKey} is unreferenced`);\n }\n }\n\n return Object.freeze({\n permutationCount,\n uniqueBodyCount: bodies.size\n });\n}\n\nfunction normalizeAxes(value)\n{\n if (!Array.isArray(value) || value.length > UINT8_MAX)\n {\n throw new TypeError(\"Effect permutation axes must be an array\");\n }\n\n const names = new Set();\n return value.map((axis, index) =>\n {\n if (!axis || typeof axis !== \"object\"\n || typeof axis.name !== \"string\" || !axis.name\n || axis.name !== axis.name.trim()\n || names.has(axis.name)\n || !Array.isArray(axis.options) || !axis.options.length\n || axis.options.length > UINT8_MAX\n || !Number.isSafeInteger(axis.defaultOption)\n || axis.defaultOption < 0\n || axis.defaultOption >= axis.options.length\n || typeof axis.description !== \"string\"\n || !Number.isSafeInteger(axis.type)\n || axis.type < 0 || axis.type > UINT8_MAX)\n {\n throw new Error(`Effect permutation axis ${index} is malformed`);\n }\n names.add(axis.name);\n\n const options = new Set();\n for (const option of axis.options)\n {\n if (typeof option !== \"string\" || !option\n || option !== option.trim() || options.has(option))\n {\n throw new Error(\n `Effect permutation axis ${axis.name} has malformed options`\n );\n }\n options.add(option);\n }\n\n return Object.freeze({\n index,\n name: axis.name,\n options: Object.freeze(axis.options.slice()),\n defaultOption: axis.defaultOption,\n description: axis.description,\n type: axis.type\n });\n });\n}\n\nfunction validateGraphAxes(value)\n{\n if (!Array.isArray(value) || value.length > UINT8_MAX)\n {\n throw new Error(\"PGRF axes must be an array\");\n }\n\n const names = new Set();\n return value.map((axis, index) =>\n {\n if (!axis || typeof axis !== \"object\" || Array.isArray(axis)\n || axis.index !== index\n || typeof axis.name !== \"string\" || !axis.name\n || axis.name !== axis.name.trim() || names.has(axis.name)\n || !Array.isArray(axis.options) || !axis.options.length\n || axis.options.length > UINT8_MAX\n || !Number.isSafeInteger(axis.defaultOption)\n || axis.defaultOption < 0\n || axis.defaultOption >= axis.options.length\n || typeof axis.description !== \"string\"\n || !Number.isSafeInteger(axis.type)\n || axis.type < 0 || axis.type > UINT8_MAX)\n {\n throw new Error(`PGRF axis ${index} is malformed or duplicated`);\n }\n names.add(axis.name);\n\n const options = new Set();\n for (const option of axis.options)\n {\n if (typeof option !== \"string\" || !option\n || option !== option.trim() || options.has(option))\n {\n throw new Error(`PGRF axis ${index} options are malformed`);\n }\n options.add(option);\n }\n return axis;\n });\n}\n\nfunction permutationProduct(axes)\n{\n let product = 1;\n for (const axis of axes)\n {\n product *= axis.options.length;\n if (!Number.isSafeInteger(product) || product < 1\n || product > MAX_EFFECT_PERMUTATIONS)\n {\n throw new Error(\n `Effect permutation count above the implementation limit `\n + `${MAX_EFFECT_PERMUTATIONS} is not supported`\n );\n }\n }\n return product;\n}\n\nfunction decodeOptionIndices(permutationIndex, axes)\n{\n let value = permutationIndex;\n return axes.map((axis) =>\n {\n const optionIndex = value % axis.options.length;\n value = Math.floor(value / axis.options.length);\n return optionIndex;\n });\n}\n\nfunction normalizeSourceRecord(record, permutationIndex, sourceByteLength)\n{\n if (!record || typeof record !== \"object\"\n || record.index !== permutationIndex\n || !Number.isSafeInteger(record.offset) || record.offset < 0\n || record.offset > UINT32_MAX\n || !Number.isSafeInteger(record.size) || record.size < 1\n || record.size > UINT32_MAX\n || !Number.isSafeInteger(record.end)\n || record.end !== record.offset + record.size\n || record.end > sourceByteLength)\n {\n throw new Error(\n `Effect permutation ${permutationIndex} has an invalid source body record`\n );\n }\n\n return Object.freeze({\n offset: record.offset,\n byteLength: record.size\n });\n}\n\nfunction validateGraphSourceRecord(record, permutationIndex, sourceByteLength)\n{\n const offset = record?.offset;\n const byteLength = record?.byteLength;\n const end = offset + byteLength;\n if (!record || typeof record !== \"object\" || Array.isArray(record)\n || !Number.isSafeInteger(offset) || offset < 0 || offset > UINT32_MAX\n || !Number.isSafeInteger(byteLength) || byteLength < 1\n || byteLength > UINT32_MAX\n || !Number.isSafeInteger(end)\n || (sourceByteLength !== undefined\n && (!Number.isSafeInteger(sourceByteLength)\n || sourceByteLength < 1\n || end > sourceByteLength)))\n {\n throw new Error(\n `PGRF variant ${permutationIndex} source record is malformed`\n );\n }\n return record;\n}\n\nfunction validateDisjointSourceRecords(records, message)\n{\n const uniqueRanges = new Map();\n for (const record of records)\n {\n const key = `${record.offset}:${record.byteLength}`;\n if (!uniqueRanges.has(key))\n {\n uniqueRanges.set(key, {\n offset: record.offset,\n end: record.offset + record.byteLength\n });\n }\n }\n\n const orderedRanges = Array.from(uniqueRanges.values())\n .sort((left, right) => left.offset - right.offset || left.end - right.end);\n for (let index = 1; index < orderedRanges.length; index += 1)\n {\n if (orderedRanges[index].offset < orderedRanges[index - 1].end)\n {\n throw new Error(message);\n }\n }\n}\n\nfunction bytesEqual(left, right)\n{\n return left.byteLength === right.byteLength\n && left.every((value, index) => value === right[index]);\n}\n"],"names":["EFFECT_PERMUTATION_GRAPH_FORMAT","EFFECT_PERMUTATION_GRAPH_VERSION","EFFECT_PERMUTATION_GRAPH_CHUNK","SHA256","UINT8_MAX","UINT32_MAX","MAX_EFFECT_PERMUTATIONS","buildEffectPermutationGraph","effectRes","TypeError","sourceBytes","m_data","Uint8Array","axes","normalizeAxes","m_permutations","permutationCount","permutationProduct","offsets","m_offsets","Array","isArray","length","m_offsetCount","Error","sourceRecords","map","record","permutationIndex","normalizeSourceRecord","byteLength","validateDisjointSourceRecords","bodies","bodyCandidatesByDigest","Map","bodyBySourceRecord","variants","sourceRecord","sourceRecordKey","offset","body","get","bodyBytes","subarray","digest","sha256Bytes","find","candidate","bytesEqual","bytes","has","Object","freeze","key","sha256","set","push","optionIndices","decodeOptionIndices","bodyKey","graph","format","formatVersion","coverage","permutations","reflection","validateEffectPermutationGraph","sourceByteLength","options","validateGraphAxes","bodyDigests","Set","bodyIndex","entries","trim","Number","isSafeInteger","test","add","references","bodyKeyBySourceRecord","variant","expectedOptionIndices","some","value","index","validateGraphSourceRecord","recordKey","existingBodyKey","uniqueBodyCount","size","names","axis","name","defaultOption","description","type","option","slice","product","optionIndex","Math","floor","end","undefined","records","message","uniqueRanges","orderedRanges","from","values","sort","left","right","every"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"effectPermutationGraph.js","sources":["../../../../src/format/effect/effectPermutationGraph.js"],"sourcesContent":["import { sha256Bytes } from \"./sha256.js\";\r\n\r\n/**\r\n * The source permutation topology: which permutations exist, and which of them\r\n * share one body.\r\n *\r\n * This module used to model that as the `PGRF` **chunk** - it exported the tag,\r\n * and every error it raised named it. There are no chunks. A `.carbonwebgpu` or\r\n * `.carbonwebgl` file is one Carbon v15 record container, and the graph the\r\n * container publishes is a *view* over the header's own permutation records and\r\n * offset table, not a stored document beside them. The chunk vocabulary outlived\r\n * the reader beneath it by weeks precisely because nothing was broken: packages\r\n * built, ccpwgl rendered, and the only cost was that every error message named a\r\n * container the file no longer had.\r\n *\r\n * The graph is still built here, from the decoded effect resource, because that\r\n * is where the source topology is known. What is gone is the claim that it is\r\n * stored anywhere.\r\n */\r\n\r\nexport const EFFECT_PERMUTATION_GRAPH_FORMAT = \"CJS_EFFECT_PERMUTATION_GRAPH\";\r\nexport const EFFECT_PERMUTATION_GRAPH_VERSION = 1;\r\n\r\nconst SHA256 = /^[0-9a-f]{64}$/u;\r\nconst UINT8_MAX = 0xff;\r\nconst UINT32_MAX = 0xffffffff;\r\nconst MAX_EFFECT_PERMUTATIONS = 0x10000;\r\n\r\n/**\r\n * Build a complete source permutation topology without claiming that every\r\n * body has portable reflection or backend programs.\r\n *\r\n * @param {object} effectRes Raw format-hlsl effect resource.\r\n * @returns {object} JSON-safe permutation graph.\r\n */\r\nexport function buildEffectPermutationGraph(effectRes)\r\n{\r\n if (!effectRes || typeof effectRes !== \"object\")\r\n {\r\n throw new TypeError(\"Effect permutation graph requires a decoded effect resource\");\r\n }\r\n\r\n const sourceBytes = effectRes.m_data;\r\n if (!(sourceBytes instanceof Uint8Array))\r\n {\r\n throw new TypeError(\"Effect permutation graph requires exact source bytes\");\r\n }\r\n\r\n const axes = normalizeAxes(effectRes.m_permutations);\r\n const permutationCount = permutationProduct(axes);\r\n const offsets = effectRes.m_offsets;\r\n if (!Array.isArray(offsets) || offsets.length !== permutationCount\r\n || effectRes.m_offsetCount !== offsets.length)\r\n {\r\n throw new Error(\r\n \"Effect permutation graph requires one source body record per permutation\"\r\n );\r\n }\r\n\r\n const sourceRecords = offsets.map((record, permutationIndex) =>\r\n normalizeSourceRecord(\r\n record,\r\n permutationIndex,\r\n sourceBytes.byteLength\r\n ));\r\n validateDisjointSourceRecords(\r\n sourceRecords,\r\n \"Effect permutation source body records partially overlap\"\r\n );\r\n\r\n const bodies = [];\r\n const bodyCandidatesByDigest = new Map();\r\n const bodyBySourceRecord = new Map();\r\n const variants = sourceRecords.map((sourceRecord, permutationIndex) =>\r\n {\r\n const sourceRecordKey = `${sourceRecord.offset}:${sourceRecord.byteLength}`;\r\n let body = bodyBySourceRecord.get(sourceRecordKey);\r\n if (!body)\r\n {\r\n const bodyBytes = sourceBytes.subarray(\r\n sourceRecord.offset,\r\n sourceRecord.offset + sourceRecord.byteLength\r\n );\r\n const digest = sha256Bytes(bodyBytes);\r\n body = (bodyCandidatesByDigest.get(digest) || [])\r\n .find((candidate) => bytesEqual(candidate.bytes, bodyBytes));\r\n if (!body && bodyCandidatesByDigest.has(digest))\r\n {\r\n throw new Error(\r\n \"Effect permutation graph body SHA-256 collision detected\"\r\n );\r\n }\r\n if (!body)\r\n {\r\n body = {\r\n bytes: bodyBytes,\r\n record: Object.freeze({\r\n key: `body${bodies.length}`,\r\n byteLength: bodyBytes.byteLength,\r\n sha256: digest\r\n })\r\n };\r\n bodyCandidatesByDigest.set(digest, [ body ]);\r\n bodies.push(body.record);\r\n }\r\n bodyBySourceRecord.set(sourceRecordKey, body);\r\n }\r\n\r\n return Object.freeze({\r\n permutationIndex,\r\n optionIndices: Object.freeze(decodeOptionIndices(\r\n permutationIndex,\r\n axes\r\n )),\r\n bodyKey: body.record.key,\r\n sourceRecord\r\n });\r\n });\r\n\r\n const graph = Object.freeze({\r\n format: EFFECT_PERMUTATION_GRAPH_FORMAT,\r\n formatVersion: EFFECT_PERMUTATION_GRAPH_VERSION,\r\n coverage: Object.freeze({\r\n permutations: \"complete\",\r\n bodies: \"identity-only\",\r\n reflection: \"absent\"\r\n }),\r\n axes: Object.freeze(axes),\r\n variants: Object.freeze(variants),\r\n bodies: Object.freeze(bodies)\r\n });\r\n\r\n validateEffectPermutationGraph(graph, {\r\n sourceByteLength: sourceBytes.byteLength\r\n });\r\n return graph;\r\n}\r\n\r\n/**\r\n * Validate a source permutation graph independently of the original effect\r\n * bytes.\r\n *\r\n * @param {object} graph Candidate graph.\r\n * @param {object} [options] Optional source-envelope limits.\r\n * @param {number} [options.sourceByteLength] Exact enclosing source byte length.\r\n * @returns {{permutationCount:number,uniqueBodyCount:number}} Validated counts.\r\n */\r\nexport function validateEffectPermutationGraph(graph, options = {})\r\n{\r\n if (!graph || typeof graph !== \"object\" || Array.isArray(graph)\r\n || graph.format !== EFFECT_PERMUTATION_GRAPH_FORMAT\r\n || graph.formatVersion !== EFFECT_PERMUTATION_GRAPH_VERSION\r\n || !graph.coverage || typeof graph.coverage !== \"object\"\r\n || Array.isArray(graph.coverage)\r\n || graph.coverage.permutations !== \"complete\"\r\n || graph.coverage.bodies !== \"identity-only\"\r\n || graph.coverage.reflection !== \"absent\")\r\n {\r\n throw new Error(\"Effect permutation graph schema or coverage is unsupported\");\r\n }\r\n\r\n const axes = validateGraphAxes(graph.axes);\r\n const permutationCount = permutationProduct(axes);\r\n if (!Array.isArray(graph.variants)\r\n || graph.variants.length !== permutationCount)\r\n {\r\n throw new Error(\r\n \"Effect permutation graph must contain one variant per Cartesian permutation\"\r\n );\r\n }\r\n if (!Array.isArray(graph.bodies)\r\n || !graph.bodies.length\r\n || graph.bodies.length > graph.variants.length)\r\n {\r\n throw new Error(\"Effect permutation graph bodies are malformed\");\r\n }\r\n\r\n const bodies = new Map();\r\n const bodyDigests = new Set();\r\n for (const [ bodyIndex, body ] of graph.bodies.entries())\r\n {\r\n if (!body || typeof body !== \"object\" || Array.isArray(body)\r\n || typeof body.key !== \"string\" || !body.key\r\n || body.key !== body.key.trim()\r\n || !Number.isSafeInteger(body.byteLength) || body.byteLength < 1\r\n || body.byteLength > UINT32_MAX\r\n || typeof body.sha256 !== \"string\" || !SHA256.test(body.sha256)\r\n || bodies.has(body.key)\r\n || bodyDigests.has(body.sha256))\r\n {\r\n throw new Error(`Effect permutation graph body ${bodyIndex} is malformed or duplicated`);\r\n }\r\n bodyDigests.add(body.sha256);\r\n bodies.set(body.key, {\r\n byteLength: body.byteLength,\r\n references: 0\r\n });\r\n }\r\n\r\n const bodyKeyBySourceRecord = new Map();\r\n const sourceRecords = [];\r\n for (const [ permutationIndex, variant ] of graph.variants.entries())\r\n {\r\n const expectedOptionIndices = decodeOptionIndices(permutationIndex, axes);\r\n if (!variant || typeof variant !== \"object\" || Array.isArray(variant)\r\n || variant.permutationIndex !== permutationIndex\r\n || !Array.isArray(variant.optionIndices)\r\n || variant.optionIndices.length !== expectedOptionIndices.length\r\n || variant.optionIndices.some((value, index) =>\r\n value !== expectedOptionIndices[index])\r\n || typeof variant.bodyKey !== \"string\"\r\n || !bodies.has(variant.bodyKey))\r\n {\r\n throw new Error(`Effect permutation graph variant ${permutationIndex} is malformed`);\r\n }\r\n\r\n const sourceRecord = validateGraphSourceRecord(\r\n variant.sourceRecord,\r\n permutationIndex,\r\n options.sourceByteLength\r\n );\r\n const body = bodies.get(variant.bodyKey);\r\n if (sourceRecord.byteLength !== body.byteLength)\r\n {\r\n throw new Error(\r\n `Effect permutation graph variant ${permutationIndex} body length disagrees`\r\n );\r\n }\r\n\r\n const recordKey = `${sourceRecord.offset}:${sourceRecord.byteLength}`;\r\n const existingBodyKey = bodyKeyBySourceRecord.get(recordKey);\r\n if (existingBodyKey && existingBodyKey !== variant.bodyKey)\r\n {\r\n throw new Error(\r\n `Effect permutation graph source record ${recordKey} maps to multiple bodies`\r\n );\r\n }\r\n bodyKeyBySourceRecord.set(recordKey, variant.bodyKey);\r\n sourceRecords.push(sourceRecord);\r\n body.references += 1;\r\n }\r\n\r\n validateDisjointSourceRecords(\r\n sourceRecords,\r\n \"Effect permutation graph source body records partially overlap\"\r\n );\r\n\r\n for (const [ bodyKey, body ] of bodies)\r\n {\r\n if (!body.references)\r\n {\r\n throw new Error(`Effect permutation graph body ${bodyKey} is unreferenced`);\r\n }\r\n }\r\n\r\n return Object.freeze({\r\n permutationCount,\r\n uniqueBodyCount: bodies.size\r\n });\r\n}\r\n\r\nfunction normalizeAxes(value)\r\n{\r\n if (!Array.isArray(value) || value.length > UINT8_MAX)\r\n {\r\n throw new TypeError(\"Effect permutation axes must be an array\");\r\n }\r\n\r\n const names = new Set();\r\n return value.map((axis, index) =>\r\n {\r\n if (!axis || typeof axis !== \"object\"\r\n || typeof axis.name !== \"string\" || !axis.name\r\n || axis.name !== axis.name.trim()\r\n || names.has(axis.name)\r\n || !Array.isArray(axis.options) || !axis.options.length\r\n || axis.options.length > UINT8_MAX\r\n || !Number.isSafeInteger(axis.defaultOption)\r\n || axis.defaultOption < 0\r\n || axis.defaultOption >= axis.options.length\r\n || typeof axis.description !== \"string\"\r\n || !Number.isSafeInteger(axis.type)\r\n || axis.type < 0 || axis.type > UINT8_MAX)\r\n {\r\n throw new Error(`Effect permutation axis ${index} is malformed`);\r\n }\r\n names.add(axis.name);\r\n\r\n const options = new Set();\r\n for (const option of axis.options)\r\n {\r\n if (typeof option !== \"string\" || !option\r\n || option !== option.trim() || options.has(option))\r\n {\r\n throw new Error(\r\n `Effect permutation axis ${axis.name} has malformed options`\r\n );\r\n }\r\n options.add(option);\r\n }\r\n\r\n return Object.freeze({\r\n index,\r\n name: axis.name,\r\n options: Object.freeze(axis.options.slice()),\r\n defaultOption: axis.defaultOption,\r\n description: axis.description,\r\n type: axis.type\r\n });\r\n });\r\n}\r\n\r\nfunction validateGraphAxes(value)\r\n{\r\n if (!Array.isArray(value) || value.length > UINT8_MAX)\r\n {\r\n throw new Error(\"Effect permutation graph axes must be an array\");\r\n }\r\n\r\n const names = new Set();\r\n return value.map((axis, index) =>\r\n {\r\n if (!axis || typeof axis !== \"object\" || Array.isArray(axis)\r\n || axis.index !== index\r\n || typeof axis.name !== \"string\" || !axis.name\r\n || axis.name !== axis.name.trim() || names.has(axis.name)\r\n || !Array.isArray(axis.options) || !axis.options.length\r\n || axis.options.length > UINT8_MAX\r\n || !Number.isSafeInteger(axis.defaultOption)\r\n || axis.defaultOption < 0\r\n || axis.defaultOption >= axis.options.length\r\n || typeof axis.description !== \"string\"\r\n || !Number.isSafeInteger(axis.type)\r\n || axis.type < 0 || axis.type > UINT8_MAX)\r\n {\r\n throw new Error(`Effect permutation graph axis ${index} is malformed or duplicated`);\r\n }\r\n names.add(axis.name);\r\n\r\n const options = new Set();\r\n for (const option of axis.options)\r\n {\r\n if (typeof option !== \"string\" || !option\r\n || option !== option.trim() || options.has(option))\r\n {\r\n throw new Error(`Effect permutation graph axis ${index} options are malformed`);\r\n }\r\n options.add(option);\r\n }\r\n return axis;\r\n });\r\n}\r\n\r\nfunction permutationProduct(axes)\r\n{\r\n let product = 1;\r\n for (const axis of axes)\r\n {\r\n product *= axis.options.length;\r\n if (!Number.isSafeInteger(product) || product < 1\r\n || product > MAX_EFFECT_PERMUTATIONS)\r\n {\r\n throw new Error(\r\n `Effect permutation count above the implementation limit `\r\n + `${MAX_EFFECT_PERMUTATIONS} is not supported`\r\n );\r\n }\r\n }\r\n return product;\r\n}\r\n\r\nfunction decodeOptionIndices(permutationIndex, axes)\r\n{\r\n let value = permutationIndex;\r\n return axes.map((axis) =>\r\n {\r\n const optionIndex = value % axis.options.length;\r\n value = Math.floor(value / axis.options.length);\r\n return optionIndex;\r\n });\r\n}\r\n\r\nfunction normalizeSourceRecord(record, permutationIndex, sourceByteLength)\r\n{\r\n if (!record || typeof record !== \"object\"\r\n || record.index !== permutationIndex\r\n || !Number.isSafeInteger(record.offset) || record.offset < 0\r\n || record.offset > UINT32_MAX\r\n || !Number.isSafeInteger(record.size) || record.size < 1\r\n || record.size > UINT32_MAX\r\n || !Number.isSafeInteger(record.end)\r\n || record.end !== record.offset + record.size\r\n || record.end > sourceByteLength)\r\n {\r\n throw new Error(\r\n `Effect permutation ${permutationIndex} has an invalid source body record`\r\n );\r\n }\r\n\r\n return Object.freeze({\r\n offset: record.offset,\r\n byteLength: record.size\r\n });\r\n}\r\n\r\nfunction validateGraphSourceRecord(record, permutationIndex, sourceByteLength)\r\n{\r\n const offset = record?.offset;\r\n const byteLength = record?.byteLength;\r\n const end = offset + byteLength;\r\n if (!record || typeof record !== \"object\" || Array.isArray(record)\r\n || !Number.isSafeInteger(offset) || offset < 0 || offset > UINT32_MAX\r\n || !Number.isSafeInteger(byteLength) || byteLength < 1\r\n || byteLength > UINT32_MAX\r\n || !Number.isSafeInteger(end)\r\n || (sourceByteLength !== undefined\r\n && (!Number.isSafeInteger(sourceByteLength)\r\n || sourceByteLength < 1\r\n || end > sourceByteLength)))\r\n {\r\n throw new Error(\r\n `Effect permutation graph variant ${permutationIndex} source record is malformed`\r\n );\r\n }\r\n return record;\r\n}\r\n\r\nfunction validateDisjointSourceRecords(records, message)\r\n{\r\n const uniqueRanges = new Map();\r\n for (const record of records)\r\n {\r\n const key = `${record.offset}:${record.byteLength}`;\r\n if (!uniqueRanges.has(key))\r\n {\r\n uniqueRanges.set(key, {\r\n offset: record.offset,\r\n end: record.offset + record.byteLength\r\n });\r\n }\r\n }\r\n\r\n const orderedRanges = Array.from(uniqueRanges.values())\r\n .sort((left, right) => left.offset - right.offset || left.end - right.end);\r\n for (let index = 1; index < orderedRanges.length; index += 1)\r\n {\r\n if (orderedRanges[index].offset < orderedRanges[index - 1].end)\r\n {\r\n throw new Error(message);\r\n }\r\n }\r\n}\r\n\r\nfunction bytesEqual(left, right)\r\n{\r\n return left.byteLength === right.byteLength\r\n && left.every((value, index) => value === right[index]);\r\n}\r\n"],"names":["EFFECT_PERMUTATION_GRAPH_FORMAT","EFFECT_PERMUTATION_GRAPH_VERSION","SHA256","UINT8_MAX","UINT32_MAX","MAX_EFFECT_PERMUTATIONS","buildEffectPermutationGraph","effectRes","TypeError","sourceBytes","m_data","Uint8Array","axes","normalizeAxes","m_permutations","permutationCount","permutationProduct","offsets","m_offsets","Array","isArray","length","m_offsetCount","Error","sourceRecords","map","record","permutationIndex","normalizeSourceRecord","byteLength","validateDisjointSourceRecords","bodies","bodyCandidatesByDigest","Map","bodyBySourceRecord","variants","sourceRecord","sourceRecordKey","offset","body","get","bodyBytes","subarray","digest","sha256Bytes","find","candidate","bytesEqual","bytes","has","Object","freeze","key","sha256","set","push","optionIndices","decodeOptionIndices","bodyKey","graph","format","formatVersion","coverage","permutations","reflection","validateEffectPermutationGraph","sourceByteLength","options","validateGraphAxes","bodyDigests","Set","bodyIndex","entries","trim","Number","isSafeInteger","test","add","references","bodyKeyBySourceRecord","variant","expectedOptionIndices","some","value","index","validateGraphSourceRecord","recordKey","existingBodyKey","uniqueBodyCount","size","names","axis","name","defaultOption","description","type","option","slice","product","optionIndex","Math","floor","end","undefined","records","message","uniqueRanges","orderedRanges","from","values","sort","left","right","every"],"mappings":"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"}
|
package/dist/format/index.js
CHANGED
|
@@ -4,7 +4,7 @@ export { CjsByteReader } from './CjsByteReader.js';
|
|
|
4
4
|
export { CjsByteWriter } from './CjsByteWriter.js';
|
|
5
5
|
export { CJS_STRING_TABLE_NULL_REFERENCE, CjsStringTable, compareTableBlobs } from './CjsStringTable.js';
|
|
6
6
|
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 } from './carbonEffect/carbonEffectRecords.js';
|
|
7
|
-
export { CARBON_BACKEND_RESOURCE_KIND, CARBON_BACKEND_VISIBILITY,
|
|
7
|
+
export { CARBON_BACKEND_RESOURCE_KIND, CARBON_BACKEND_VISIBILITY, readBackendBlock, writeBackendBlock } from './carbonEffect/carbonEffectBackendBlock.js';
|
|
8
8
|
export { CARBON_EFFECT_RECORD_BYTES, CARBON_EFFECT_SOURCE_HASH_BYTES, CjsCarbonEffectBodyReader, CjsCarbonEffectReader, looksLikeCarbonEffectContainer } from './carbonEffect/CjsCarbonEffectReader.js';
|
|
9
9
|
export { CjsCarbonEffectWriter, writeCarbonEffectFile } from './carbonEffect/CjsCarbonEffectWriter.js';
|
|
10
10
|
export { CARBON_BACKEND_TRANSFORM_FAMILY, DETAIL_MAP_ARRAY_DEFAULTS } from './carbonEffect/carbonEffectResourceTransform.js';
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* The WebGL 2 motivation is a hard limit rather than tidiness: the affected
|
|
18
18
|
* shaders sit at exactly 16 textures against a 16-unit guarantee, so merging
|
|
19
19
|
* three maps into one is what creates the headroom lighting needs. See
|
|
20
|
-
*
|
|
20
|
+
* the WebGL2 sampler-unit limit of 16.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
/** Resource names that make up the family, in layer order. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detailMapFamily.js","sources":["../../../../../src/formats/hlsl/core/detailMapFamily.js"],"sourcesContent":["/**\n * Recognises Carbon's Detail-map resource family from reflection alone.\n *\n * Both backends merge `Detail1Map`/`Detail2Map`/`Detail3Map` into a single\n * array texture, and both need to agree exactly on *which* registers take part.\n * That decision is about the resources, not about the shading language, so it\n * lives here rather than twice in the two emitters.\n *\n * What this module does **not** do is prove the merge is safe. Recognising the\n * family is necessary but not sufficient: a backend must also confirm that every\n * use of those registers is a plain sample it can redirect at an array layer. A\n * detail map fetched by integer coordinate, or queried for its size, cannot be\n * merged, and only the code walking the shader can see that. So each backend\n * pairs this recogniser with its own use check and fails closed on anything it\n * does not understand.\n *\n * The WebGL 2 motivation is a hard limit rather than tidiness: the affected\n * shaders sit at exactly 16 textures against a 16-unit guarantee, so merging\n * three maps into one is what creates the headroom lighting needs. See\n *
|
|
1
|
+
{"version":3,"file":"detailMapFamily.js","sources":["../../../../../src/formats/hlsl/core/detailMapFamily.js"],"sourcesContent":["/**\n * Recognises Carbon's Detail-map resource family from reflection alone.\n *\n * Both backends merge `Detail1Map`/`Detail2Map`/`Detail3Map` into a single\n * array texture, and both need to agree exactly on *which* registers take part.\n * That decision is about the resources, not about the shading language, so it\n * lives here rather than twice in the two emitters.\n *\n * What this module does **not** do is prove the merge is safe. Recognising the\n * family is necessary but not sufficient: a backend must also confirm that every\n * use of those registers is a plain sample it can redirect at an array layer. A\n * detail map fetched by integer coordinate, or queried for its size, cannot be\n * merged, and only the code walking the shader can see that. So each backend\n * pairs this recogniser with its own use check and fails closed on anything it\n * does not understand.\n *\n * The WebGL 2 motivation is a hard limit rather than tidiness: the affected\n * shaders sit at exactly 16 textures against a 16-unit guarantee, so merging\n * three maps into one is what creates the headroom lighting needs. See\n * the WebGL2 sampler-unit limit of 16.\n */\n\n/** Resource names that make up the family, in layer order. */\nconst DETAIL_PARAMETERS = Object.freeze([ \"Detail1Map\", \"Detail2Map\", \"Detail3Map\" ]);\n\n/** Carbon's resource type code for a 2D texture. */\nconst CARBON_TEXTURE_2D = 2;\n\n/** The merged array's name, and the transform family it belongs to. */\nexport const DETAIL_MAP_ARRAY_NAME = \"DetailArrayMap\";\nexport const DETAIL_MAP_ARRAY_FAMILY = \"detail-map-array\";\n\n/**\n * Recognises the detail-map family in one stage's reflected resources.\n *\n * Requires the maps to be contiguous from `Detail1Map` with no gap, in one\n * register space, at strictly ascending registers, and each an ordinary\n * single-element 2D texture declared linear. Anything else returns null: a\n * partial or unusual family is not merged, because guessing produces a shader\n * that links and samples the wrong thing.\n *\n * `isSRGB` must be present and false rather than merely not true. Carbon's\n * reader always sets it, so an absent flag means the caller is passing\n * something other than resource reflection, and the layers of one array texture\n * cannot disagree about whether sampling decodes sRGB.\n *\n * @param {Array<object>} resources Reflected resources, each carrying\n * `registerIndex`, `name`, `type`, `isSRGB`, and optionally `registerSpace`\n * and `arrayElements`. `parameter` is accepted in place of `name`.\n * @param {object} [options] Recognition options.\n * @param {number} [options.registerSpace] Default register space.\n * @returns {object|null} Frozen plan, or null when the family is absent or unusable.\n */\nexport function recogniseDetailMapFamily(resources, options = {})\n{\n const registerSpace = options.registerSpace ?? 0;\n const byParameter = new Map();\n\n for (const resource of resources ?? [])\n {\n const value = resource?.toJSON?.() ?? resource;\n const name = value?.name ?? value?.parameter;\n if (typeof name !== \"string\" || !DETAIL_PARAMETERS.includes(name)) continue;\n\n // A duplicate name means the reflection is not what this recogniser\n // assumes, so it declines rather than picking one.\n if (byParameter.has(name)) return null;\n byParameter.set(name, { registerIndex: value.registerIndex, value });\n }\n\n if (byParameter.size < 2) return null;\n\n // Contiguous from Detail1Map: {1,2} and {1,2,3} merge, {1,3} does not.\n const parameters = DETAIL_PARAMETERS.slice(0, byParameter.size);\n if (parameters.some((parameter) => !byParameter.has(parameter))) return null;\n\n const layers = [];\n for (const [ layer, parameter ] of parameters.entries())\n {\n const { registerIndex, value } = byParameter.get(parameter);\n\n if (!Number.isInteger(registerIndex) || registerIndex < 0\n || value.type !== CARBON_TEXTURE_2D\n || (value.arrayElements ?? 1) !== 1\n || value.isSRGB !== false)\n {\n return null;\n }\n\n const space = value.registerSpace ?? registerSpace;\n\n // One array texture occupies one binding, so the layers cannot come\n // from different register spaces.\n if (layer > 0 && space !== layers[layer - 1].registerSpace) return null;\n if (layer > 0 && registerIndex <= layers[layer - 1].registerIndex) return null;\n\n layers.push({ parameter, layer, registerIndex, registerSpace: space });\n }\n\n return Object.freeze({\n family: DETAIL_MAP_ARRAY_FAMILY,\n outputName: DETAIL_MAP_ARRAY_NAME,\n registerSpace,\n layerCount: layers.length,\n layers: Object.freeze(layers.map((entry) => Object.freeze(entry))),\n registers: Object.freeze(layers.map((entry) => entry.registerIndex))\n });\n}\n\n/**\n * Builds the transform record the container's shared transform section stores.\n *\n * @param {object} plan Recognised family plan.\n * @param {string} layoutKey Enclosing pass key.\n * @returns {object} Transform record.\n */\nexport function detailMapTransformFor(plan, layoutKey)\n{\n return {\n id: `${layoutKey}:${DETAIL_MAP_ARRAY_FAMILY}:sampled-resource:${plan.registerSpace}:${plan.registers[0]}`,\n family: DETAIL_MAP_ARRAY_FAMILY,\n layoutKey,\n inputs: plan.layers.map((entry) => ({\n registerSpace: entry.registerSpace,\n registerIndex: entry.registerIndex,\n parameter: entry.parameter\n }))\n };\n}\n\nexport default recogniseDetailMapFamily;\n"],"names":["DETAIL_PARAMETERS","Object","freeze","CARBON_TEXTURE_2D","DETAIL_MAP_ARRAY_NAME","DETAIL_MAP_ARRAY_FAMILY","recogniseDetailMapFamily","resources","options","registerSpace","byParameter","Map","resource","value","toJSON","name","parameter","includes","has","set","registerIndex","size","parameters","slice","some","layers","layer","entries","get","Number","isInteger","type","arrayElements","isSRGB","space","push","family","outputName","layerCount","length","map","entry","registers","detailMapTransformFor","plan","layoutKey","id","inputs"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* fixed — one permutation binds the family at t11/t12/t13 and another at
|
|
14
14
|
* t13/t14/t15 — so this is name-driven and must stay that way.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
16
|
+
* Those two sampler units matter against the WebGL2 limit of 16.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
/** The structured buffers, both required for the family to be recognised. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localLightFamily.js","sources":["../../../../../src/formats/hlsl/core/localLightFamily.js"],"sourcesContent":["/**\n * Recognises Carbon's local-light resource family from reflection alone.\n *\n * Carbon puts local lights in two structured buffers plus an optional profile\n * texture. On a backend with storage buffers this needs no attention at all —\n * WebGPU binds them natively and loses nothing. WebGL 2 has no structured\n * buffers, so the same two resources have to be re-expressed as data textures,\n * and something has to say which registers they were.\n *\n * That \"which registers\" question is what this module answers, and it is\n * backend-neutral for the same reason the detail-map recogniser is: it is a fact\n * about Carbon's resources, not about a shading language. The registers are not\n * fixed — one permutation binds the family at t11/t12/t13 and another at\n * t13/t14/t15 — so this is name-driven and must stay that way.\n *\n *
|
|
1
|
+
{"version":3,"file":"localLightFamily.js","sources":["../../../../../src/formats/hlsl/core/localLightFamily.js"],"sourcesContent":["/**\n * Recognises Carbon's local-light resource family from reflection alone.\n *\n * Carbon puts local lights in two structured buffers plus an optional profile\n * texture. On a backend with storage buffers this needs no attention at all —\n * WebGPU binds them natively and loses nothing. WebGL 2 has no structured\n * buffers, so the same two resources have to be re-expressed as data textures,\n * and something has to say which registers they were.\n *\n * That \"which registers\" question is what this module answers, and it is\n * backend-neutral for the same reason the detail-map recogniser is: it is a fact\n * about Carbon's resources, not about a shading language. The registers are not\n * fixed — one permutation binds the family at t11/t12/t13 and another at\n * t13/t14/t15 — so this is name-driven and must stay that way.\n *\n * Those two sampler units matter against the WebGL2 limit of 16.\n */\n\n/** The structured buffers, both required for the family to be recognised. */\nconst LIGHT_INDEX_BUFFER = \"LightIndexBuffer\";\nconst LIGHT_DATA_BUFFER = \"LightBuffer\";\n\n/** The profile texture, which is optional. */\nconst LIGHT_PROFILE_ARRAY = \"LightProfileArray\";\n\n/** Every resource name in the family, for callers that need to strip them. */\nexport const LOCAL_LIGHT_RESOURCE_NAMES = Object.freeze([\n LIGHT_INDEX_BUFFER,\n LIGHT_DATA_BUFFER,\n LIGHT_PROFILE_ARRAY\n]);\n\n/** Carbon's resource type code for a structured buffer, as `BoneTransforms` uses. */\nconst CARBON_STRUCTURED_BUFFER = 7;\n\n/**\n * Recognises the local-light family in one stage's reflected resources.\n *\n * Both structured buffers are required. The profile array is not: some\n * permutations never sample it, and a lowering may substitute neutral\n * attenuation for it. Returning a plan with `profileRegister: null` is a\n * different statement from returning null, and callers depend on the difference.\n *\n * @param {Array<object>} resources Reflected resources, each carrying\n * `registerIndex`, `name` and `type`.\n * @returns {object|null} Frozen plan, or null when the family is absent.\n */\nexport function recogniseLocalLightFamily(resources)\n{\n const byName = new Map();\n\n for (const resource of resources ?? [])\n {\n const value = resource?.toJSON?.() ?? resource;\n const name = value?.name;\n if (typeof name !== \"string\" || !LOCAL_LIGHT_RESOURCE_NAMES.includes(name)) continue;\n if (byName.has(name)) return null;\n byName.set(name, value);\n }\n\n const index = byName.get(LIGHT_INDEX_BUFFER);\n const data = byName.get(LIGHT_DATA_BUFFER);\n if (!index || !data) return null;\n\n // Both must actually be structured buffers. A same-named 2D texture is not\n // this family, and lowering it as though it were would misread every light.\n if (index.type !== CARBON_STRUCTURED_BUFFER || data.type !== CARBON_STRUCTURED_BUFFER)\n {\n return null;\n }\n if (!Number.isInteger(index.registerIndex) || !Number.isInteger(data.registerIndex))\n {\n return null;\n }\n\n const profile = byName.get(LIGHT_PROFILE_ARRAY);\n\n return Object.freeze({\n indexRegister: index.registerIndex,\n dataRegister: data.registerIndex,\n profileRegister: Number.isInteger(profile?.registerIndex) ? profile.registerIndex : null,\n registers: Object.freeze(\n [ index.registerIndex, data.registerIndex, profile?.registerIndex ]\n .filter((register) => Number.isInteger(register))\n .sort((a, b) => a - b)\n )\n });\n}\n\n/**\n * Removes the local-light resource bindings from a binding manifest.\n *\n * Needed when the family is dropped rather than lowered: the emitter no longer\n * declares those resources, and a consumer that still sees them in the manifest\n * tries to build textures for resources the shader does not have.\n *\n * Mutates in place, matching the manifest's own conventions.\n *\n * @param {object} manifestJson Serialized binding manifest.\n * @returns {object} The same manifest, light resource bindings removed.\n */\nexport function stripLocalLightBindings(manifestJson)\n{\n for (const stage of manifestJson?.stages ?? [])\n {\n stage.bindings = (stage.bindings ?? []).filter((binding) =>\n {\n if (binding?.kind !== \"resource\") return true;\n const name = binding.metadataName || binding.carbon?.name;\n return !LOCAL_LIGHT_RESOURCE_NAMES.includes(name);\n });\n }\n return manifestJson;\n}\n\n/** Transform family recording a profile array replaced by a constant. */\nexport const LOCAL_LIGHT_PROFILE_NEUTRAL_FAMILY = \"local-light-profile-neutral\";\n\n/**\n * Builds the resource transform recording that `LightProfileArray` was replaced\n * by a constant one.\n *\n * A transform rather than a binding because nothing is bound: the resource is\n * gone and its samples are a literal. What has to survive is the *statement*\n * that it was dropped deliberately, since a described Carbon resource with no\n * declaration and no record is exactly what the integrity rules treat as lost.\n *\n * The single input is the profile register itself. `detail-map-array` lists\n * several inputs because it merges them into one output; this family has no\n * output at all, so its input list names only the resource that went away.\n *\n * @param {object} plan Recognised local-light family.\n * @param {string} layoutKey Enclosing pass key.\n * @returns {object|null} Transform record, or null when there is no profile.\n */\nexport function localLightProfileNeutralTransformFor(plan, layoutKey)\n{\n if (!Number.isInteger(plan?.profileRegister)) return null;\n\n const registerSpace = plan.registerSpace ?? 0;\n return {\n id: `${layoutKey}:${LOCAL_LIGHT_PROFILE_NEUTRAL_FAMILY}:sampled-resource:${registerSpace}:${plan.profileRegister}`,\n family: LOCAL_LIGHT_PROFILE_NEUTRAL_FAMILY,\n layoutKey,\n inputs: [ {\n registerSpace,\n registerIndex: plan.profileRegister,\n parameter: LIGHT_PROFILE_ARRAY\n } ]\n };\n}\n\nexport default recogniseLocalLightFamily;\n"],"names":["LIGHT_INDEX_BUFFER","LIGHT_DATA_BUFFER","LIGHT_PROFILE_ARRAY","LOCAL_LIGHT_RESOURCE_NAMES","Object","freeze","CARBON_STRUCTURED_BUFFER","recogniseLocalLightFamily","resources","byName","Map","resource","value","toJSON","name","includes","has","set","index","get","data","type","Number","isInteger","registerIndex","profile","indexRegister","dataRegister","profileRegister","registers","filter","register","sort","a","b","stripLocalLightBindings","manifestJson","stage","stages","bindings","binding","kind","metadataName","carbon","LOCAL_LIGHT_PROFILE_NEUTRAL_FAMILY","localLightProfileNeutralTransformFor","plan","layoutKey","registerSpace","id","family","inputs","parameter"],"mappings":"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"}
|
|
@@ -387,7 +387,7 @@ function readPngChunks(bytes) {
|
|
|
387
387
|
return chunks;
|
|
388
388
|
}
|
|
389
389
|
function readPngChunkSummary(bytes) {
|
|
390
|
-
let
|
|
390
|
+
let cursor = 8;
|
|
391
391
|
let chunkCount = 0;
|
|
392
392
|
let idatChunkCount = 0;
|
|
393
393
|
let idatBytes = 0;
|
|
@@ -396,10 +396,12 @@ function readPngChunkSummary(bytes) {
|
|
|
396
396
|
let hasSrgb = false;
|
|
397
397
|
let hasIend = false;
|
|
398
398
|
let chunksComplete = true;
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
const
|
|
399
|
+
let pngOffset = null;
|
|
400
|
+
let physicalPixelDimensions = null;
|
|
401
|
+
while (cursor + 12 <= bytes.byteLength) {
|
|
402
|
+
const length = readU32BE(bytes, cursor);
|
|
403
|
+
const type = String.fromCharCode(bytes[cursor + 4], bytes[cursor + 5], bytes[cursor + 6], bytes[cursor + 7]);
|
|
404
|
+
const end = cursor + 8 + length;
|
|
403
405
|
if (end + 4 > bytes.byteLength) {
|
|
404
406
|
chunksComplete = false;
|
|
405
407
|
break;
|
|
@@ -408,8 +410,20 @@ function readPngChunkSummary(bytes) {
|
|
|
408
410
|
if (type === "IDAT") {
|
|
409
411
|
idatChunkCount++;
|
|
410
412
|
idatBytes += length;
|
|
411
|
-
} else if (type === "PLTE") hasPalette = true;else if (type === "tRNS") hasTransparency = true;else if (type === "sRGB") hasSrgb = true;else if (type === "
|
|
412
|
-
|
|
413
|
+
} else if (type === "PLTE") hasPalette = true;else if (type === "tRNS") hasTransparency = true;else if (type === "sRGB") hasSrgb = true;else if (type === "oFFs" && length === 9) {
|
|
414
|
+
pngOffset = {
|
|
415
|
+
x: readI32BE(bytes, cursor + 8),
|
|
416
|
+
y: readI32BE(bytes, cursor + 12),
|
|
417
|
+
unit: bytes[cursor + 16]
|
|
418
|
+
};
|
|
419
|
+
} else if (type === "pHYs" && length === 9) {
|
|
420
|
+
physicalPixelDimensions = {
|
|
421
|
+
x: readU32BE(bytes, cursor + 8),
|
|
422
|
+
y: readU32BE(bytes, cursor + 12),
|
|
423
|
+
unit: bytes[cursor + 16]
|
|
424
|
+
};
|
|
425
|
+
} else if (type === "IEND") hasIend = true;
|
|
426
|
+
cursor = end + 4;
|
|
413
427
|
if (type === "IEND") break;
|
|
414
428
|
}
|
|
415
429
|
return {
|
|
@@ -420,7 +434,9 @@ function readPngChunkSummary(bytes) {
|
|
|
420
434
|
hasTransparency,
|
|
421
435
|
hasSrgb,
|
|
422
436
|
hasIend,
|
|
423
|
-
chunksComplete
|
|
437
|
+
chunksComplete,
|
|
438
|
+
offset: pngOffset,
|
|
439
|
+
physicalPixelDimensions
|
|
424
440
|
};
|
|
425
441
|
}
|
|
426
442
|
function concatBytes(chunks) {
|
|
@@ -624,6 +640,9 @@ function readU16LE(bytes, offset) {
|
|
|
624
640
|
function readU32BE(bytes, offset) {
|
|
625
641
|
return bytes[offset] * 0x1000000 + (bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
|
|
626
642
|
}
|
|
643
|
+
function readI32BE(bytes, offset) {
|
|
644
|
+
return new DataView(bytes.buffer, bytes.byteOffset + offset, 4).getInt32(0, false);
|
|
645
|
+
}
|
|
627
646
|
function readU32LE(bytes, offset) {
|
|
628
647
|
return (bytes[offset] | bytes[offset + 1] << 8 | bytes[offset + 2] << 16 | bytes[offset + 3] * 0x1000000) >>> 0;
|
|
629
648
|
}
|