@carbonenginejs/runtime-resource 0.17.0 → 0.18.1
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/carbonEffect/CjsCarbonEffectWriter.js +16 -4
- package/dist/format/carbonEffect/CjsCarbonEffectWriter.js.map +1 -1
- package/dist/format/carbonEffect/backendEngineId.js +1 -3
- package/dist/format/carbonEffect/backendEngineId.js.map +1 -1
- package/dist/format/carbonEffect/buildCarbonEffectContainer.js +11 -1
- package/dist/format/carbonEffect/buildCarbonEffectContainer.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js +38 -1
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectRecords.js +45 -1
- package/dist/format/carbonEffect/carbonEffectRecords.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectResourceTransform.js +120 -60
- 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/dds/core/helpers.js +35 -6
- package/dist/formats/dds/core/helpers.js.map +1 -1
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js +53 -1
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js.map +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/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +10 -1
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js.map +1 -1
- package/dist/formats/index.js +3 -0
- package/dist/formats/index.js.map +1 -1
- package/dist/formats/schemabound/CjsSchemaBoundFormat.js +236 -0
- package/dist/formats/schemabound/CjsSchemaBoundFormat.js.map +1 -0
- package/dist/formats/schemabound/core/schemaBoundErrors.js +9 -0
- package/dist/formats/schemabound/core/schemaBoundErrors.js.map +1 -0
- package/dist/formats/schemabound/core/schemaBoundValues.js +307 -0
- package/dist/formats/schemabound/core/schemaBoundValues.js.map +1 -0
- package/dist/formats/schemabound/index.js +2 -0
- package/dist/formats/schemabound/index.js.map +1 -0
- package/dist/formats/sqlite/CjsSqliteFormat.js +244 -0
- package/dist/formats/sqlite/CjsSqliteFormat.js.map +1 -0
- package/dist/formats/sqlite/core/sqlitePages.js +159 -0
- package/dist/formats/sqlite/core/sqlitePages.js.map +1 -0
- package/dist/formats/sqlite/core/sqliteRecords.js +174 -0
- package/dist/formats/sqlite/core/sqliteRecords.js.map +1 -0
- package/dist/formats/sqlite/core/sqliteSchema.js +100 -0
- package/dist/formats/sqlite/core/sqliteSchema.js.map +1 -0
- package/dist/formats/sqlite/index.js +2 -0
- package/dist/formats/sqlite/index.js.map +1 -0
- package/dist/formats/static/CjsStaticFormat.js +220 -0
- package/dist/formats/static/CjsStaticFormat.js.map +1 -0
- package/dist/formats/static/index.js +2 -0
- package/dist/formats/static/index.js.map +1 -0
- package/dist/formats/webgl/core/buildGlslEffectContainer.js +3 -1
- package/dist/formats/webgl/core/buildGlslEffectContainer.js.map +1 -1
- package/dist/formats/webgl/core/effectPackage.js +13 -5
- package/dist/formats/webgl/core/effectPackage.js.map +1 -1
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +10 -2
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
- package/dist/formats/webgl/core/glslBackendBlock.js +6 -5
- 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/webgpu/CjsWebgpuFormat.js +161 -163
- package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js +3 -1
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js.map +1 -1
- package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js +179 -131
- package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js.map +1 -1
- package/dist/formats/webgpu/core/effectBackendBodySet.js +2 -3
- 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 +44 -33
- package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +9 -1
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js +14 -0
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
- package/docs/concepts/shader-resource-model.md +34 -1
- package/docs/formats/README.md +21 -0
- package/docs/formats/carbon-effect-container.md +54 -27
- package/docs/formats/schemabound.md +112 -0
- package/docs/formats/static.md +119 -0
- package/docs/formats/webgl/README.md +5 -3
- package/docs/formats/webgpu/README.md +2 -2
- package/docs/formats/webgpu/architecture.md +2 -2
- package/docs/formats/webgpu/formats/carbon-webgpu.md +24 -6
- package/docs/formats/webgpu/guides/effect-packaging.md +1 -2
- package/docs/formats/webgpu/reference/api.md +7 -6
- package/docs/formats/webgpu/reference/wgsl-compatibility.md +2 -2
- package/docs/reference/classes/formats.md +33 -0
- package/package.json +5 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carbonEffectResourceTransform.js","sources":["../../../../src/format/carbonEffect/carbonEffectResourceTransform.js"],"sourcesContent":["import { CjsFormatWriteError, CjsFormatReadError } from \"../CjsFormatError.js\";\n\n/**\n * The resource-transform section, shared by every backend's per-pass block.\n *\n * A resource transform is a recipe for building one backend resource out of\n * several Carbon ones. It is deliberately backend-neutral: `detail-map-array`\n * merges `Detail1Map`, `Detail2Map` and `Detail3Map` into one array texture, and\n * that decision is about the *resources*, not about WGSL or GLSL. Both backends\n * want the identical merge, for different reasons - WebGPU to reduce binding\n * churn, WebGL 2 because the family otherwise needs 17 texture units against a\n * limit of 16 (docs/contracts/webgl2-texture-budget.md).\n *\n * So the section lives here rather than in either backend's block codec, and the\n * two codecs compose it. A transform written by one backend decodes identically\n * under the other.\n */\n\n/**\n * Resource-transform families. The discriminator exists so `kind`,\n * `representation`, `missingLayer` and the output name stay derivable without\n * pinning the format to one recognizer: a second family costs an enum value\n * rather than a format version bump.\n */\nexport const CARBON_BACKEND_TRANSFORM_FAMILY = Object.freeze([\n \"detail-map-array\",\n \"local-light-profile-neutral\"\n]);\n\n/** Constants a `detail-map-array` transform restores rather than storing. */\nexport const DETAIL_MAP_ARRAY_DEFAULTS = Object.freeze({\n version: 1,\n kind: \"texture-2d-array\",\n stage: \"fragment\",\n representation: \"native-or-rgba8\",\n missingLayer: \"reject\",\n viewDimension: \"2d-array\",\n outputName: \"DetailArrayMap\"\n});\n\n/**\n * Constants a `local-light-profile-neutral` transform restores rather than\n * storing.\n *\n * Unlike `detail-map-array` this transform has no output resource: its whole\n * content is that an input resource was replaced by a constant. It exists so a\n * described Carbon resource that the backend deliberately dropped is still\n * accounted for - a resource that simply disappears is indistinguishable from\n * one that was lost, and the integrity rules reject that on purpose.\n *\n * `LightProfileArray` is multiplied into a light's attenuation, so the constant\n * is one, not zero. That is the same value the shader's own no-profile path\n * produces, which is why dropping it is neutral rather than dark.\n */\nexport const LOCAL_LIGHT_PROFILE_NEUTRAL_DEFAULTS = Object.freeze({\n version: 1,\n kind: \"constant\",\n stage: \"fragment\",\n representation: \"constant-one\",\n missingLayer: \"ignore\",\n viewDimension: null,\n outputName: null\n});\n\n/**\n * Per-family constant sets, keyed by family name.\n *\n * The reader restores these rather than storing them, so a family that omitted\n * its entry here would silently inherit another family's constants.\n */\nconst TRANSFORM_DEFAULTS_BY_FAMILY = Object.freeze({\n \"detail-map-array\": DETAIL_MAP_ARRAY_DEFAULTS,\n \"local-light-profile-neutral\": LOCAL_LIGHT_PROFILE_NEUTRAL_DEFAULTS\n});\n\n/**\n * Writes a length-prefixed UTF-8 string.\n *\n * @param {object} writer Target byte writer.\n * @param {string} value Text value.\n */\nexport function writeInlineString(writer, value)\n{\n const bytes = new TextEncoder().encode(String(value ?? \"\"));\n if (bytes.length > 0xffff)\n {\n throw new CjsFormatWriteError(\"Backend block string exceeds 65535 bytes\", {\n byteLength: bytes.length\n });\n }\n writer.u16(bytes.length);\n writer.bytes(bytes);\n}\n\n/**\n * Reads a length-prefixed UTF-8 string.\n *\n * @param {object} reader Source byte reader.\n * @returns {string} Decoded text.\n */\nexport function readInlineString(reader)\n{\n const length = reader.readUint16();\n return new TextDecoder(\"utf-8\", { fatal: false }).decode(reader.readRaw(length));\n}\n\n/**\n * Writes the count-prefixed resource-transform section.\n *\n * @param {object} writer Target byte writer.\n * @param {object[]} transforms Resource transforms.\n */\nexport function writeTransformSection(writer, transforms)\n{\n writer.u8(transforms.length);\n\n for (const transform of transforms)\n {\n const family = CARBON_BACKEND_TRANSFORM_FAMILY.indexOf(transform.family ?? \"detail-map-array\");\n if (family < 0)\n {\n throw new CjsFormatWriteError(`Unknown transform family \"${transform.family}\"`, {\n family: transform.family\n });\n }\n writer.u8(family);\n // `id` stays on the wire: a caller may supply it, and it propagates into\n // the engine binding as `transformId`. Deriving it would foreclose the\n // caller-supplied plan path to save four bytes.\n writeInlineString(writer, transform.id);\n writer.u8(transform.inputs.length);\n for (const input of transform.inputs)\n {\n // Array position is the layer. Safe because `parameter` stays on the\n // wire, so layer identity remains cross-checkable rather than\n // asserted by position.\n writer.u8(input.registerSpace);\n writer.u8(input.registerIndex);\n writeInlineString(writer, input.parameter);\n }\n }\n}\n\n/**\n * Reads the count-prefixed resource-transform section, restoring derived fields.\n *\n * @param {object} reader Source byte reader.\n * @param {string|null} layoutKey Enclosing pass key, restored onto records.\n * @returns {object[]} Resource transforms.\n */\nexport function readTransformSection(reader, layoutKey)\n{\n const transforms = [];\n const transformCount = reader.readUint8();\n\n for (let index = 0; index < transformCount; index += 1)\n {\n const family = CARBON_BACKEND_TRANSFORM_FAMILY[reader.readUint8()];\n const defaults = TRANSFORM_DEFAULTS_BY_FAMILY[family];\n if (!defaults)\n {\n throw new CjsFormatReadError(`Transform family \"${family}\" has no restored constants`, {\n family\n });\n }\n const id = readInlineString(reader);\n const inputs = [];\n const inputCount = reader.readUint8();\n for (let layer = 0; layer < inputCount; layer += 1)\n {\n const registerSpace = reader.readUint8();\n const registerIndex = reader.readUint8();\n const parameter = readInlineString(reader);\n const identity = `sampled-resource:${registerSpace}:${registerIndex}`;\n inputs.push({\n parameter,\n layer,\n // Kept alongside the identity they compose: a consumer checking\n // the transform against a binding set compares registers, and\n // re-parsing them back out of the identity string is a second\n // place for the format of that string to matter.\n registerSpace,\n registerIndex,\n identity,\n scopeIdentity: `${identity}@${defaults.stage}`\n });\n }\n\n transforms.push({\n id,\n family,\n version: defaults.version,\n kind: defaults.kind,\n stage: defaults.stage,\n representation: defaults.representation,\n missingLayer: defaults.missingLayer,\n layoutKey,\n inputs,\n output: {\n name: defaults.outputName,\n viewDimension: defaults.viewDimension,\n layerCount: inputs.length,\n identity: inputs[0]?.identity ?? null,\n scopeIdentity: inputs[0]?.scopeIdentity ?? null\n }\n });\n }\n\n return transforms;\n}\n"],"names":["CARBON_BACKEND_TRANSFORM_FAMILY","Object","freeze","DETAIL_MAP_ARRAY_DEFAULTS","version","kind","stage","representation","missingLayer","viewDimension","outputName","LOCAL_LIGHT_PROFILE_NEUTRAL_DEFAULTS","TRANSFORM_DEFAULTS_BY_FAMILY","writeInlineString","writer","value","bytes","TextEncoder","encode","String","length","CjsFormatWriteError","byteLength","u16","readInlineString","reader","readUint16","TextDecoder","fatal","decode","readRaw","writeTransformSection","transforms","u8","transform","family","indexOf","id","inputs","input","registerSpace","registerIndex","parameter","readTransformSection","layoutKey","transformCount","readUint8","index","defaults","CjsFormatReadError","inputCount","layer","identity","push","scopeIdentity","output","name","layerCount"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"carbonEffectResourceTransform.js","sources":["../../../../src/format/carbonEffect/carbonEffectResourceTransform.js"],"sourcesContent":["import { CjsFormatWriteError, CjsFormatReadError } from \"../CjsFormatError.js\";\r\nimport { DETAIL_MAP_ARRAY_NAME } from \"../../formats/hlsl/core/detailMapFamily.js\";\r\n\r\n/**\r\n * The resource-transform section, shared by every backend's per-pass block.\r\n *\r\n * A resource transform is a recipe for building one backend resource out of\r\n * several Carbon ones. It is deliberately backend-neutral: `detail-map-array`\r\n * merges `Detail1Map`, `Detail2Map` and `Detail3Map` into one array texture, and\r\n * that decision is about the *resources*, not about WGSL or GLSL. Both backends\r\n * want the identical merge, for different reasons - WebGPU to reduce binding\r\n * churn, WebGL 2 because the family otherwise needs 17 texture units against a\r\n * limit of 16.\r\n *\r\n * So the section lives here rather than in either backend's block codec, and the\r\n * two codecs compose it. A transform written by one backend decodes identically\r\n * under the other.\r\n */\r\n\r\n/**\r\n * Resource-transform families. The discriminator exists so `kind`,\r\n * `representation`, `missingLayer` and the output name stay derivable without\r\n * pinning the format to one recognizer: a second family costs an enum value\r\n * rather than a format version bump.\r\n */\r\nexport const CARBON_BACKEND_TRANSFORM_FAMILY = Object.freeze([\r\n \"detail-map-array\",\r\n \"local-light-profile-neutral\"\r\n]);\r\n\r\n/** Constants a `detail-map-array` transform restores rather than storing. */\r\nexport const DETAIL_MAP_ARRAY_DEFAULTS = Object.freeze({\r\n version: 1,\r\n kind: \"texture-2d-array\",\r\n stage: \"fragment\",\r\n representation: \"native-or-rgba8\",\r\n missingLayer: \"reject\",\r\n viewDimension: \"2d-array\",\r\n // The merged array's name is owned by the detail-map family, not restated\r\n // here. It has been renamed once already (DetailMapArray -> DetailArrayMap),\r\n // and a second literal is a second place for the next rename to miss.\r\n outputName: DETAIL_MAP_ARRAY_NAME\r\n});\r\n\r\n/**\r\n * Constants a `local-light-profile-neutral` transform restores rather than\r\n * storing.\r\n *\r\n * Unlike `detail-map-array` this transform has no output resource: its whole\r\n * content is that an input resource was replaced by a constant. It exists so a\r\n * described Carbon resource that the backend deliberately dropped is still\r\n * accounted for - a resource that simply disappears is indistinguishable from\r\n * one that was lost, and the integrity rules reject that on purpose.\r\n *\r\n * `LightProfileArray` is multiplied into a light's attenuation, so the constant\r\n * is one, not zero. That is the same value the shader's own no-profile path\r\n * produces, which is why dropping it is neutral rather than dark.\r\n */\r\nexport const LOCAL_LIGHT_PROFILE_NEUTRAL_DEFAULTS = Object.freeze({\r\n version: 1,\r\n kind: \"constant\",\r\n stage: \"fragment\",\r\n representation: \"constant-one\",\r\n missingLayer: \"ignore\",\r\n viewDimension: null,\r\n outputName: null\r\n});\r\n\r\n/**\r\n * Per-family constant sets, keyed by family name.\r\n *\r\n * The reader restores these rather than storing them, so a family that omitted\r\n * its entry here would silently inherit another family's constants.\r\n */\r\nconst TRANSFORM_DEFAULTS_BY_FAMILY = Object.freeze({\r\n \"detail-map-array\": DETAIL_MAP_ARRAY_DEFAULTS,\r\n \"local-light-profile-neutral\": LOCAL_LIGHT_PROFILE_NEUTRAL_DEFAULTS\r\n});\r\n\r\n/**\r\n * Refuses a transform whose restored fields disagree with its family.\r\n *\r\n * Every field below is dropped on write and rebuilt from the family constants\r\n * on read, so a document that disagrees does not fail - it round-trips into a\r\n * *different* document, which is the failure shape that produced both the\r\n * `selectedOptions` and the register-pair bugs. A caller may supply its own\r\n * transform plan, so agreement is checked here rather than assumed from the\r\n * one producer that happens to emit constants.\r\n *\r\n * An absent field is not a disagreement: omitting it is the normal way to say\r\n * \"restore the family value\".\r\n *\r\n * @param {object} transform Resource transform.\r\n * @param {string} family Resolved family name.\r\n * @param {object} defaults Family constants the reader restores.\r\n */\r\nfunction assertRestoredFieldsAgree(transform, family, defaults)\r\n{\r\n const restored = [\r\n [ \"version\", transform.version, defaults.version ],\r\n [ \"kind\", transform.kind, defaults.kind ],\r\n [ \"stage\", transform.stage, defaults.stage ],\r\n [ \"representation\", transform.representation, defaults.representation ],\r\n [ \"missingLayer\", transform.missingLayer, defaults.missingLayer ],\r\n [ \"output.name\", transform.output?.name, defaults.outputName ],\r\n [ \"output.viewDimension\", transform.output?.viewDimension, defaults.viewDimension ]\r\n ];\r\n\r\n for (const [ field, actual, expected ] of restored)\r\n {\r\n if (actual === undefined || actual === null) continue;\r\n if (actual === expected) continue;\r\n\r\n throw new CjsFormatWriteError(\r\n `Resource transform \"${transform.id}\" sets ${field} to ${JSON.stringify(actual)}, but the`\r\n + ` \"${family}\" family restores ${JSON.stringify(expected)} on read. The value is not`\r\n + ` stored, so writing this would silently change the document.`,\r\n { transform: transform.id, family, field, actual, expected }\r\n );\r\n }\r\n\r\n // Layer count is positional on the wire: the reader counts the inputs it\r\n // read. A document claiming a different count is claiming something the\r\n // bytes cannot carry.\r\n const layerCount = transform.output?.layerCount;\r\n\r\n if (layerCount !== undefined && layerCount !== null && layerCount !== transform.inputs.length)\r\n {\r\n throw new CjsFormatWriteError(\r\n `Resource transform \"${transform.id}\" declares ${layerCount} output layers but carries`\r\n + ` ${transform.inputs.length} inputs; the reader derives the count from the inputs.`,\r\n { transform: transform.id, family, declared: layerCount, inputs: transform.inputs.length }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Writes a length-prefixed UTF-8 string.\r\n *\r\n * @param {object} writer Target byte writer.\r\n * @param {string} value Text value.\r\n */\r\nexport function writeInlineString(writer, value)\r\n{\r\n const bytes = new TextEncoder().encode(String(value ?? \"\"));\r\n if (bytes.length > 0xffff)\r\n {\r\n throw new CjsFormatWriteError(\"Backend block string exceeds 65535 bytes\", {\r\n byteLength: bytes.length\r\n });\r\n }\r\n writer.u16(bytes.length);\r\n writer.bytes(bytes);\r\n}\r\n\r\n/**\r\n * Reads a length-prefixed UTF-8 string.\r\n *\r\n * @param {object} reader Source byte reader.\r\n * @returns {string} Decoded text.\r\n */\r\nexport function readInlineString(reader)\r\n{\r\n const length = reader.readUint16();\r\n return new TextDecoder(\"utf-8\", { fatal: false }).decode(reader.readRaw(length));\r\n}\r\n\r\n/**\r\n * Writes the count-prefixed resource-transform section.\r\n *\r\n * @param {object} writer Target byte writer.\r\n * @param {object[]} transforms Resource transforms.\r\n */\r\nexport function writeTransformSection(writer, transforms)\r\n{\r\n writer.u8(transforms.length);\r\n\r\n for (const transform of transforms)\r\n {\r\n const familyName = transform.family ?? \"detail-map-array\";\r\n const family = CARBON_BACKEND_TRANSFORM_FAMILY.indexOf(familyName);\r\n if (family < 0)\r\n {\r\n throw new CjsFormatWriteError(`Unknown transform family \"${transform.family}\"`, {\r\n family: transform.family\r\n });\r\n }\r\n assertRestoredFieldsAgree(transform, familyName, TRANSFORM_DEFAULTS_BY_FAMILY[familyName]);\r\n writer.u8(family);\r\n // `id` stays on the wire: a caller may supply it, and it propagates into\r\n // the engine binding as `transformId`. Deriving it would foreclose the\r\n // caller-supplied plan path to save four bytes.\r\n writeInlineString(writer, transform.id);\r\n writer.u8(transform.inputs.length);\r\n for (const input of transform.inputs)\r\n {\r\n // Array position is the layer. Safe because `parameter` stays on the\r\n // wire, so layer identity remains cross-checkable rather than\r\n // asserted by position.\r\n //\r\n // Checked rather than trusted: the reader rebuilds each input's\r\n // identity from this pair, so a producer that omits it does not fail\r\n // here -- it writes two zero bytes and every layer reads back as\r\n // register 0. That is a wrong package that loads, which is worse\r\n // than one that throws.\r\n if (!Number.isInteger(input.registerSpace) || !Number.isInteger(input.registerIndex))\r\n {\r\n throw new TypeError(\r\n `Resource transform input ${input.parameter} needs integer registerSpace and`\r\n + ` registerIndex; the reader rebuilds its identity from them`\r\n );\r\n }\r\n writer.u8(input.registerSpace);\r\n writer.u8(input.registerIndex);\r\n writeInlineString(writer, input.parameter);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Reads the count-prefixed resource-transform section, restoring derived fields.\r\n *\r\n * @param {object} reader Source byte reader.\r\n * @param {string|null} layoutKey Enclosing pass key, restored onto records.\r\n * @returns {object[]} Resource transforms.\r\n */\r\nexport function readTransformSection(reader, layoutKey)\r\n{\r\n const transforms = [];\r\n const transformCount = reader.readUint8();\r\n\r\n for (let index = 0; index < transformCount; index += 1)\r\n {\r\n const family = CARBON_BACKEND_TRANSFORM_FAMILY[reader.readUint8()];\r\n const defaults = TRANSFORM_DEFAULTS_BY_FAMILY[family];\r\n if (!defaults)\r\n {\r\n throw new CjsFormatReadError(`Transform family \"${family}\" has no restored constants`, {\r\n family\r\n });\r\n }\r\n const id = readInlineString(reader);\r\n const inputs = [];\r\n const inputCount = reader.readUint8();\r\n for (let layer = 0; layer < inputCount; layer += 1)\r\n {\r\n const registerSpace = reader.readUint8();\r\n const registerIndex = reader.readUint8();\r\n const parameter = readInlineString(reader);\r\n const identity = `sampled-resource:${registerSpace}:${registerIndex}`;\r\n inputs.push({\r\n parameter,\r\n layer,\r\n // Kept alongside the identity they compose: a consumer checking\r\n // the transform against a binding set compares registers, and\r\n // re-parsing them back out of the identity string is a second\r\n // place for the format of that string to matter.\r\n registerSpace,\r\n registerIndex,\r\n identity,\r\n scopeIdentity: `${identity}@${defaults.stage}`\r\n });\r\n }\r\n\r\n transforms.push({\r\n id,\r\n family,\r\n version: defaults.version,\r\n kind: defaults.kind,\r\n stage: defaults.stage,\r\n representation: defaults.representation,\r\n missingLayer: defaults.missingLayer,\r\n layoutKey,\r\n inputs,\r\n output: {\r\n name: defaults.outputName,\r\n viewDimension: defaults.viewDimension,\r\n layerCount: inputs.length,\r\n identity: inputs[0]?.identity ?? null,\r\n scopeIdentity: inputs[0]?.scopeIdentity ?? null\r\n }\r\n });\r\n }\r\n\r\n return transforms;\r\n}\r\n"],"names":["CARBON_BACKEND_TRANSFORM_FAMILY","Object","freeze","DETAIL_MAP_ARRAY_DEFAULTS","version","kind","stage","representation","missingLayer","viewDimension","outputName","DETAIL_MAP_ARRAY_NAME","LOCAL_LIGHT_PROFILE_NEUTRAL_DEFAULTS","TRANSFORM_DEFAULTS_BY_FAMILY","assertRestoredFieldsAgree","transform","family","defaults","restored","output","name","field","actual","expected","undefined","CjsFormatWriteError","id","JSON","stringify","layerCount","inputs","length","declared","writeInlineString","writer","value","bytes","TextEncoder","encode","String","byteLength","u16","readInlineString","reader","readUint16","TextDecoder","fatal","decode","readRaw","writeTransformSection","transforms","u8","familyName","indexOf","input","Number","isInteger","registerSpace","registerIndex","TypeError","parameter","readTransformSection","layoutKey","transformCount","readUint8","index","CjsFormatReadError","inputCount","layer","identity","push","scopeIdentity"],"mappings":"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"}
|
|
@@ -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
|
@@ -3,7 +3,7 @@ export { CjsFormatReadError, CjsFormatWriteError } from './CjsFormatError.js';
|
|
|
3
3
|
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
|
-
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';
|
|
6
|
+
export { CARBON_ANNOTATION_TYPE, CARBON_EFFECT_COUNT_CAPS, CARBON_EFFECT_DATA_VERSION, CARBON_EFFECT_MIN_DATA_VERSION, CARBON_EFFECT_WRITE_VERSIONS, CARBON_SHADER_CONSTANTS_MAX, collectArena, compareAnnotationNames, internArena, passthroughArena, readEffectDescription, resolveWriteVersion, writeEffectDescription } from './carbonEffect/carbonEffectRecords.js';
|
|
7
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';
|
|
@@ -37,6 +37,7 @@ const DXGI_PIXEL_FORMATS = Object.freeze({
|
|
|
37
37
|
6: "rgb32float",
|
|
38
38
|
10: "rgba16float",
|
|
39
39
|
16: "rg32float",
|
|
40
|
+
34: "rg16float",
|
|
40
41
|
41: "r32float",
|
|
41
42
|
54: "r16float",
|
|
42
43
|
28: "rgba8unorm",
|
|
@@ -460,7 +461,7 @@ function readDdsTexture(bytes, metadata) {
|
|
|
460
461
|
};
|
|
461
462
|
}
|
|
462
463
|
function canDecodeDdsToRgba(metadata) {
|
|
463
|
-
return ["rgba32float", "rgb32float", "rgba16float", "rg32float", "r32float", "r16float", "rgba8unorm", "rgba8unorm-srgb", "bgra8unorm", "bgra8unorm-srgb", "bgrx8unorm", "bgrx8unorm-srgb", "rgbx8unorm", "bgr8unorm", "l8unorm", "l8a8unorm", "a8unorm", "rg8unorm", "r8unorm", "bc1-rgba-unorm", "bc1-rgba-unorm-srgb", "bc2-rgba-unorm", "bc2-rgba-unorm-srgb", "bc3-rgba-unorm", "bc3-rgba-unorm-srgb", "bc4-r-unorm", "bc4-r-snorm", "bc5-rg-unorm", "bc5-rg-snorm", "bc6h-rgb-ufloat", "bc6h-rgb-float", "bc7-rgba-unorm", "bc7-rgba-unorm-srgb"].includes(metadata.pixelFormat);
|
|
464
|
+
return ["rgba32float", "rgb32float", "rgba16float", "rg32float", "rg16float", "r32float", "r16float", "rgba8unorm", "rgba8unorm-srgb", "bgra8unorm", "bgra8unorm-srgb", "bgrx8unorm", "bgrx8unorm-srgb", "rgbx8unorm", "bgr8unorm", "l8unorm", "l8a8unorm", "a8unorm", "rg8unorm", "r8unorm", "bc1-rgba-unorm", "bc1-rgba-unorm-srgb", "bc2-rgba-unorm", "bc2-rgba-unorm-srgb", "bc3-rgba-unorm", "bc3-rgba-unorm-srgb", "bc4-r-unorm", "bc4-r-snorm", "bc5-rg-unorm", "bc5-rg-snorm", "bc6h-rgb-ufloat", "bc6h-rgb-float", "bc7-rgba-unorm", "bc7-rgba-unorm-srgb"].includes(metadata.pixelFormat);
|
|
464
465
|
}
|
|
465
466
|
function readDdsToRgba(bytes, metadata) {
|
|
466
467
|
if (!canDecodeDdsToRgba(metadata)) {
|
|
@@ -563,6 +564,7 @@ function getDdsLevelLayout(pixelFormat, width, height, depth) {
|
|
|
563
564
|
"rgb32float": 12,
|
|
564
565
|
"rgba16float": 8,
|
|
565
566
|
"rg32float": 8,
|
|
567
|
+
"rg16float": 4,
|
|
566
568
|
"r32float": 4,
|
|
567
569
|
"r16float": 2,
|
|
568
570
|
"rgba8unorm": 4,
|
|
@@ -648,6 +650,7 @@ function decodeFloatUncompressed(source, metadata) {
|
|
|
648
650
|
"rgb32float": 12,
|
|
649
651
|
"rgba16float": 8,
|
|
650
652
|
"rg32float": 8,
|
|
653
|
+
"rg16float": 4,
|
|
651
654
|
"r32float": 4,
|
|
652
655
|
"r16float": 2
|
|
653
656
|
}[metadata.pixelFormat];
|
|
@@ -675,6 +678,11 @@ function decodeFloatUncompressed(source, metadata) {
|
|
|
675
678
|
green = view.getFloat32(sourceOffset + 4, true);
|
|
676
679
|
blue = 0;
|
|
677
680
|
alpha = 1;
|
|
681
|
+
} else if (metadata.pixelFormat === "rg16float") {
|
|
682
|
+
red = halfToFloat(view.getUint16(sourceOffset, true));
|
|
683
|
+
green = halfToFloat(view.getUint16(sourceOffset + 2, true));
|
|
684
|
+
blue = 0;
|
|
685
|
+
alpha = 1;
|
|
678
686
|
} else {
|
|
679
687
|
red = metadata.pixelFormat === "r16float" ? halfToFloat(view.getUint16(sourceOffset, true)) : view.getFloat32(sourceOffset, true);
|
|
680
688
|
green = red;
|
|
@@ -689,7 +697,7 @@ function decodeFloatUncompressed(source, metadata) {
|
|
|
689
697
|
return rgba;
|
|
690
698
|
}
|
|
691
699
|
function isFloatPixelFormat(pixelFormat) {
|
|
692
|
-
return typeof pixelFormat === "string" && (pixelFormat.startsWith("bc6h-") || ["rgba32float", "rgb32float", "rgba16float", "rg32float", "r32float", "r16float"].includes(pixelFormat));
|
|
700
|
+
return typeof pixelFormat === "string" && (pixelFormat.startsWith("bc6h-") || ["rgba32float", "rgb32float", "rgba16float", "rg32float", "rg16float", "r32float", "r16float"].includes(pixelFormat));
|
|
693
701
|
}
|
|
694
702
|
function halfToFloat(value) {
|
|
695
703
|
const sign = value & 0x8000 ? -1 : 1;
|
|
@@ -832,13 +840,34 @@ function decodeBc1Colors(c0, c1, forceFourColor = false) {
|
|
|
832
840
|
function decode565(value) {
|
|
833
841
|
return [Math.round((value >>> 11 & 0x1f) * 255 / 31), Math.round((value >>> 5 & 0x3f) * 255 / 63), Math.round((value & 0x1f) * 255 / 31), 255];
|
|
834
842
|
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* The floating-point `D3DFORMAT` enumerators, which a legacy DDS stores as a
|
|
846
|
+
* NUMBER in the four-character-code field rather than as four characters.
|
|
847
|
+
*
|
|
848
|
+
* That is the whole trap. `DDPF_FOURCC` is set and the field reads `114`, which
|
|
849
|
+
* as text is `"r\0\0\0"` and matches nothing, so a reader that only compares
|
|
850
|
+
* character codes reports an unrecognized format for a file whose format is
|
|
851
|
+
* perfectly ordinary. Every one of these six is a plain uncompressed surface.
|
|
852
|
+
*
|
|
853
|
+
* Two were mapped when BC6H support landed and the other four were not, so
|
|
854
|
+
* `A16B16G16R16F` and `A32B32G32R32F` loaded while their one- and two-channel
|
|
855
|
+
* siblings did not. Found 2026-08-16 on
|
|
856
|
+
* `res:/dx9/model/ship/amarr/battleship/ab3/effects/ab3_traffic.dds`, a 256x9
|
|
857
|
+
* `R32F` gradient.
|
|
858
|
+
*/
|
|
859
|
+
const LEGACY_D3DFMT_PIXEL_FORMATS = {
|
|
860
|
+
111: "r16float",
|
|
861
|
+
112: "rg16float",
|
|
862
|
+
113: "rgba16float",
|
|
863
|
+
114: "r32float",
|
|
864
|
+
115: "rg32float",
|
|
865
|
+
116: "rgba32float"
|
|
866
|
+
};
|
|
835
867
|
function getDdsPixelFormat(format) {
|
|
836
868
|
if (format.dxgiFormat) return DXGI_PIXEL_FORMATS[format.dxgiFormat] || "";
|
|
837
869
|
if (format.pfFlags & DDS_FOURCC && format.fourCc) {
|
|
838
|
-
return FOURCC_PIXEL_FORMATS[format.fourCc] ||
|
|
839
|
-
113: "rgba16float",
|
|
840
|
-
116: "rgba32float"
|
|
841
|
-
}[format.fourCcCode] || "";
|
|
870
|
+
return FOURCC_PIXEL_FORMATS[format.fourCc] || LEGACY_D3DFMT_PIXEL_FORMATS[format.fourCcCode] || "";
|
|
842
871
|
}
|
|
843
872
|
if (format.pfFlags & DDS_RGB) {
|
|
844
873
|
if (format.rgbBitCount === 32 && format.rBitMask === 0x000000ff && format.gBitMask === 0x0000ff00 && format.bBitMask === 0x00ff0000 && format.aBitMask === 0xff000000) return "rgba8unorm";
|