@carbonenginejs/runtime-resource 0.19.1 → 0.20.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/formats/webgl/core/glsl/DxbcGlslEmitter.js +59 -11
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
- package/dist/formats/webgl/core/helpers.js +2 -2
- package/dist/formats/webgl/core/helpers.js.map +1 -1
- package/dist/formats/webgl/core/readGlslEffectContainer.js +10 -1
- package/dist/formats/webgl/core/readGlslEffectContainer.js.map +1 -1
- package/package.json +1 -1
|
@@ -83,8 +83,8 @@ function isWebglEffectContainer(input) {
|
|
|
83
83
|
return false;
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
-
const EMIT_GLSL_OPTION_KEYS = new Set(["constantBufferStyle", "pixelConstantBufferRemap", "samplerName", "vertexStructuredCapacity", "dataTextureWidth", "stubResourceRegisters", "neutralResourceRegisters", "detailMapArrayRegisters", "lightConstantBuffer", "lightPackedTexture", "emulatedAddressing", "pairVaryings", "source"]);
|
|
87
|
-
const EMIT_GLSL_PROFILE_KEYS = new Set(["constantBufferStyle", "pixelConstantBufferRemap", "samplerName", "vertexStructuredCapacity", "dataTextureWidth", "stubResourceRegisters", "neutralResourceRegisters", "detailMapArrayRegisters", "lightConstantBuffer", "lightPackedTexture", "emulatedAddressing"]);
|
|
86
|
+
const EMIT_GLSL_OPTION_KEYS = new Set(["constantBufferStyle", "pixelConstantBufferRemap", "samplerName", "vertexStructuredCapacity", "dataTextureWidth", "stubResourceRegisters", "neutralResourceRegisters", "detailMapArrayRegisters", "lightConstantBuffer", "lightPackedTexture", "emulatedAddressing", "depthRange", "pairVaryings", "source"]);
|
|
87
|
+
const EMIT_GLSL_PROFILE_KEYS = new Set(["constantBufferStyle", "pixelConstantBufferRemap", "samplerName", "vertexStructuredCapacity", "dataTextureWidth", "stubResourceRegisters", "neutralResourceRegisters", "detailMapArrayRegisters", "lightConstantBuffer", "lightPackedTexture", "emulatedAddressing", "depthRange"]);
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Translates one DXBC stage into GLSL ES 3.00 source, sharing one core path
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sources":["../../../../../src/formats/webgl/core/helpers.js"],"sourcesContent":["/**\r\n * Internal glue for CjsWebglFormat.\r\n *\r\n * Keeps the public class file small: input/option normalization, DXBC-to-GLSL\r\n * emission, and JSON conversion live here. Reading an effect is\r\n * `readGlslEffectContainer` and summarising one is `inspectGlslEffectContainer`;\r\n * neither needs glue, so neither is wrapped here. The GLSL emitter lives under\r\n * src/formats/webgl/core/glsl.\r\n */\r\n\r\nimport { DxbcGlslEmitter } from \"./glsl/DxbcGlslEmitter.js\";\r\nimport { applyPackedLightFixups } from \"./glsl/packedLightFixups.js\";\r\nimport { WebglReadError } from \"./errors.js\";\r\nimport {\r\n looksLikeCarbonEffectContainer\r\n} from \"../../../format/carbonEffect/CjsCarbonEffectReader.js\";\r\n\r\nexport const OUTPUT_JSON = \"json\";\r\n\r\nexport const DEFAULT_VALUES = Object.freeze({\r\n emit: OUTPUT_JSON,\r\n source: \"memory\"\r\n});\r\n\r\nconst VALID_EMITS = new Set([ OUTPUT_JSON ]);\r\nconst OPTION_KEYS = new Set([ \"emit\", \"source\" ]);\r\n\r\n/**\r\n * Merge format values over a base set and validate them.\r\n *\r\n * @param {object} base Current values.\r\n * @param {object} [options] Values to merge in.\r\n * @param {string} [readerName] Reader name used in error messages.\r\n * @returns {object} A validated copy of the merged values.\r\n */\r\nexport function normalizeValues(base, options = {}, readerName = \"CjsWebglFormat\")\r\n{\r\n if (!options || typeof options !== \"object\")\r\n {\r\n throw new TypeError(`${readerName}: options must be an object`);\r\n }\r\n for (const key of Object.keys(options))\r\n {\r\n if (!OPTION_KEYS.has(key))\r\n {\r\n throw new TypeError(`${readerName}: unknown option ${JSON.stringify(key)}`);\r\n }\r\n }\r\n\r\n const values = { ...base, ...options };\r\n\r\n if (!VALID_EMITS.has(values.emit))\r\n {\r\n throw new TypeError(`${readerName}: emit must be \"${OUTPUT_JSON}\", got ${JSON.stringify(values.emit)}`);\r\n }\r\n if (typeof values.source !== \"string\" || !values.source)\r\n {\r\n values.source = DEFAULT_VALUES.source;\r\n }\r\n\r\n return {\r\n emit: values.emit,\r\n source: values.source\r\n };\r\n}\r\n\r\n/**\r\n * Normalize caller input into a Uint8Array of package/DXBC bytes.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|Buffer|DataView} input Candidate payload.\r\n * @returns {Uint8Array} The payload bytes.\r\n */\r\nexport function toBytes(input)\r\n{\r\n if (input instanceof Uint8Array) return input;\r\n if (typeof ArrayBuffer !== \"undefined\" && input instanceof ArrayBuffer) return new Uint8Array(input);\r\n if (ArrayBuffer.isView(input)) return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);\r\n throw new TypeError(\"CjsWebglFormat: input must be effect container bytes (Uint8Array, Buffer, DataView or ArrayBuffer)\");\r\n}\r\n\r\n/**\r\n * Reports whether a payload has the Carbon effect container shape.\r\n *\r\n * A shape check, not an identity check: our files are stock Carbon containers,\r\n * so nothing in the bytes distinguishes a WebGL one from a shipped\r\n * `effect.dx11`. Identity comes from the path the file was resolved through.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|Buffer|DataView} input Candidate payload.\r\n * @returns {boolean} True when the payload has the container shape.\r\n */\r\nexport function isWebglEffectContainer(input)\r\n{\r\n try\r\n {\r\n return looksLikeCarbonEffectContainer(toBytes(input));\r\n }\r\n catch\r\n {\r\n return false;\r\n }\r\n}\r\n\r\nconst EMIT_GLSL_OPTION_KEYS = new Set([\r\n \"constantBufferStyle\",\r\n \"pixelConstantBufferRemap\",\r\n \"samplerName\",\r\n \"vertexStructuredCapacity\",\r\n \"dataTextureWidth\",\r\n \"stubResourceRegisters\",\r\n \"neutralResourceRegisters\",\r\n \"detailMapArrayRegisters\",\r\n \"lightConstantBuffer\",\r\n \"lightPackedTexture\",\r\n \"emulatedAddressing\",\r\n \"pairVaryings\",\r\n \"source\"\r\n]);\r\n\r\nconst EMIT_GLSL_PROFILE_KEYS = new Set([\r\n \"constantBufferStyle\",\r\n \"pixelConstantBufferRemap\",\r\n \"samplerName\",\r\n \"vertexStructuredCapacity\",\r\n \"dataTextureWidth\",\r\n \"stubResourceRegisters\",\r\n \"neutralResourceRegisters\",\r\n \"detailMapArrayRegisters\",\r\n \"lightConstantBuffer\",\r\n \"lightPackedTexture\",\r\n \"emulatedAddressing\"\r\n]);\r\n\r\n/**\r\n * Translates one DXBC stage into GLSL ES 3.00 source, sharing one core path\r\n * between `CjsWebglFormat.emitGlsl` (static) and `EmitGlsl` (instance).\r\n *\r\n * `options` is a flat bag combining the emitter's ccpwgl-profile constructor\r\n * bits (`constantBufferStyle`, `pixelConstantBufferRemap`, `samplerName`,\r\n * `vertexStructuredCapacity`, `dataTextureWidth`) with its per-call Emit\r\n * options (`pairVaryings`, `source`); omitted keys keep the emitter's\r\n * existing defaults exactly.\r\n *\r\n * @param {ArrayBuffer|ArrayBufferView|Uint8Array} dxbcBytes DXBC container bytes.\r\n * @param {object} [options] Combined profile/emit options.\r\n * @returns {{source:string,stageName:string,inputs:object[],outputs:object[],bindings:object[],warnings:string[],computeFragment:(object|undefined)}}\r\n * GLSL text plus the IO contract the packaging layer records; compute\r\n * stages add the emitter's `computeFragment` host contract.\r\n */\r\nexport function emitGlslWithOptions(dxbcBytes, options = {})\r\n{\r\n if (!options || typeof options !== \"object\")\r\n {\r\n throw new TypeError(\"CjsWebglFormat: emitGlsl options must be an object\");\r\n }\r\n for (const key of Object.keys(options))\r\n {\r\n if (!EMIT_GLSL_OPTION_KEYS.has(key))\r\n {\r\n throw new TypeError(`CjsWebglFormat: unknown emitGlsl option ${JSON.stringify(key)}`);\r\n }\r\n }\r\n\r\n const profile = {};\r\n for (const key of EMIT_GLSL_PROFILE_KEYS)\r\n {\r\n if (Object.prototype.hasOwnProperty.call(options, key)) profile[key] = options[key];\r\n }\r\n\r\n const emitter = new DxbcGlslEmitter({ profile });\r\n const result = emitter.Emit(dxbcBytes, {\r\n source: options.source,\r\n pairVaryings: options.pairVaryings\r\n });\r\n\r\n // The packed local-light lowering leaves two idioms that must not reach a\r\n // driver: a flag mask round-tripped through a float, and an all-bits mask\r\n // stored as a float and then used for branch control, where 0xFFFFFFFF is a\r\n // NaN. Applied here rather than at a call site so every caller gets them.\r\n if (!options.lightPackedTexture) return result;\r\n\r\n return {\r\n ...result,\r\n source: applyPackedLightFixups(result.source, result.stageName)\r\n };\r\n}\r\n\r\n/**\r\n * Deep-convert a value to plain JSON-compatible data. Typed arrays become\r\n * plain number arrays; Maps/Sets become objects/arrays; class instances\r\n * with toJSON are honoured.\r\n *\r\n * @param {any} value Value to convert.\r\n * @returns {any} Plain data.\r\n */\r\nexport function toJsonValue(value)\r\n{\r\n if (value === null || value === undefined) return value ?? null;\r\n if (typeof value === \"number\" || typeof value === \"string\" || typeof value === \"boolean\") return value;\r\n if (typeof value === \"bigint\") return value.toString();\r\n if (ArrayBuffer.isView(value)) return Array.from(value);\r\n if (Array.isArray(value)) return value.map(toJsonValue);\r\n if (value instanceof Map)\r\n {\r\n const out = {};\r\n for (const [ key, entry ] of value) out[key] = toJsonValue(entry);\r\n return out;\r\n }\r\n if (value instanceof Set) return Array.from(value, toJsonValue);\r\n if (typeof value === \"object\")\r\n {\r\n if (typeof value.toJSON === \"function\") return toJsonValue(value.toJSON());\r\n const out = {};\r\n for (const key of Object.keys(value)) out[key] = toJsonValue(value[key]);\r\n return out;\r\n }\r\n return null;\r\n}\r\n\r\nexport { WebglReadError };\r\n"],"names":["OUTPUT_JSON","DEFAULT_VALUES","Object","freeze","emit","source","VALID_EMITS","Set","OPTION_KEYS","normalizeValues","base","options","readerName","TypeError","key","keys","has","JSON","stringify","values","toBytes","input","Uint8Array","ArrayBuffer","isView","buffer","byteOffset","byteLength","isWebglEffectContainer","looksLikeCarbonEffectContainer","EMIT_GLSL_OPTION_KEYS","EMIT_GLSL_PROFILE_KEYS","emitGlslWithOptions","dxbcBytes","profile","prototype","hasOwnProperty","call","emitter","DxbcGlslEmitter","result","Emit","pairVaryings","lightPackedTexture","applyPackedLightFixups","stageName","toJsonValue","value","undefined","toString","Array","from","isArray","map","Map","out","entry","toJSON"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"helpers.js","sources":["../../../../../src/formats/webgl/core/helpers.js"],"sourcesContent":["/**\r\n * Internal glue for CjsWebglFormat.\r\n *\r\n * Keeps the public class file small: input/option normalization, DXBC-to-GLSL\r\n * emission, and JSON conversion live here. Reading an effect is\r\n * `readGlslEffectContainer` and summarising one is `inspectGlslEffectContainer`;\r\n * neither needs glue, so neither is wrapped here. The GLSL emitter lives under\r\n * src/formats/webgl/core/glsl.\r\n */\r\n\r\nimport { DxbcGlslEmitter } from \"./glsl/DxbcGlslEmitter.js\";\r\nimport { applyPackedLightFixups } from \"./glsl/packedLightFixups.js\";\r\nimport { WebglReadError } from \"./errors.js\";\r\nimport {\r\n looksLikeCarbonEffectContainer\r\n} from \"../../../format/carbonEffect/CjsCarbonEffectReader.js\";\r\n\r\nexport const OUTPUT_JSON = \"json\";\r\n\r\nexport const DEFAULT_VALUES = Object.freeze({\r\n emit: OUTPUT_JSON,\r\n source: \"memory\"\r\n});\r\n\r\nconst VALID_EMITS = new Set([ OUTPUT_JSON ]);\r\nconst OPTION_KEYS = new Set([ \"emit\", \"source\" ]);\r\n\r\n/**\r\n * Merge format values over a base set and validate them.\r\n *\r\n * @param {object} base Current values.\r\n * @param {object} [options] Values to merge in.\r\n * @param {string} [readerName] Reader name used in error messages.\r\n * @returns {object} A validated copy of the merged values.\r\n */\r\nexport function normalizeValues(base, options = {}, readerName = \"CjsWebglFormat\")\r\n{\r\n if (!options || typeof options !== \"object\")\r\n {\r\n throw new TypeError(`${readerName}: options must be an object`);\r\n }\r\n for (const key of Object.keys(options))\r\n {\r\n if (!OPTION_KEYS.has(key))\r\n {\r\n throw new TypeError(`${readerName}: unknown option ${JSON.stringify(key)}`);\r\n }\r\n }\r\n\r\n const values = { ...base, ...options };\r\n\r\n if (!VALID_EMITS.has(values.emit))\r\n {\r\n throw new TypeError(`${readerName}: emit must be \"${OUTPUT_JSON}\", got ${JSON.stringify(values.emit)}`);\r\n }\r\n if (typeof values.source !== \"string\" || !values.source)\r\n {\r\n values.source = DEFAULT_VALUES.source;\r\n }\r\n\r\n return {\r\n emit: values.emit,\r\n source: values.source\r\n };\r\n}\r\n\r\n/**\r\n * Normalize caller input into a Uint8Array of package/DXBC bytes.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|Buffer|DataView} input Candidate payload.\r\n * @returns {Uint8Array} The payload bytes.\r\n */\r\nexport function toBytes(input)\r\n{\r\n if (input instanceof Uint8Array) return input;\r\n if (typeof ArrayBuffer !== \"undefined\" && input instanceof ArrayBuffer) return new Uint8Array(input);\r\n if (ArrayBuffer.isView(input)) return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);\r\n throw new TypeError(\"CjsWebglFormat: input must be effect container bytes (Uint8Array, Buffer, DataView or ArrayBuffer)\");\r\n}\r\n\r\n/**\r\n * Reports whether a payload has the Carbon effect container shape.\r\n *\r\n * A shape check, not an identity check: our files are stock Carbon containers,\r\n * so nothing in the bytes distinguishes a WebGL one from a shipped\r\n * `effect.dx11`. Identity comes from the path the file was resolved through.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|Buffer|DataView} input Candidate payload.\r\n * @returns {boolean} True when the payload has the container shape.\r\n */\r\nexport function isWebglEffectContainer(input)\r\n{\r\n try\r\n {\r\n return looksLikeCarbonEffectContainer(toBytes(input));\r\n }\r\n catch\r\n {\r\n return false;\r\n }\r\n}\r\n\r\nconst EMIT_GLSL_OPTION_KEYS = new Set([\r\n \"constantBufferStyle\",\r\n \"pixelConstantBufferRemap\",\r\n \"samplerName\",\r\n \"vertexStructuredCapacity\",\r\n \"dataTextureWidth\",\r\n \"stubResourceRegisters\",\r\n \"neutralResourceRegisters\",\r\n \"detailMapArrayRegisters\",\r\n \"lightConstantBuffer\",\r\n \"lightPackedTexture\",\r\n \"emulatedAddressing\",\r\n \"depthRange\",\r\n \"pairVaryings\",\r\n \"source\"\r\n]);\r\n\r\nconst EMIT_GLSL_PROFILE_KEYS = new Set([\r\n \"constantBufferStyle\",\r\n \"pixelConstantBufferRemap\",\r\n \"samplerName\",\r\n \"vertexStructuredCapacity\",\r\n \"dataTextureWidth\",\r\n \"stubResourceRegisters\",\r\n \"neutralResourceRegisters\",\r\n \"detailMapArrayRegisters\",\r\n \"lightConstantBuffer\",\r\n \"lightPackedTexture\",\r\n \"emulatedAddressing\",\r\n \"depthRange\"\r\n]);\r\n\r\n/**\r\n * Translates one DXBC stage into GLSL ES 3.00 source, sharing one core path\r\n * between `CjsWebglFormat.emitGlsl` (static) and `EmitGlsl` (instance).\r\n *\r\n * `options` is a flat bag combining the emitter's ccpwgl-profile constructor\r\n * bits (`constantBufferStyle`, `pixelConstantBufferRemap`, `samplerName`,\r\n * `vertexStructuredCapacity`, `dataTextureWidth`) with its per-call Emit\r\n * options (`pairVaryings`, `source`); omitted keys keep the emitter's\r\n * existing defaults exactly.\r\n *\r\n * @param {ArrayBuffer|ArrayBufferView|Uint8Array} dxbcBytes DXBC container bytes.\r\n * @param {object} [options] Combined profile/emit options.\r\n * @returns {{source:string,stageName:string,inputs:object[],outputs:object[],bindings:object[],warnings:string[],computeFragment:(object|undefined)}}\r\n * GLSL text plus the IO contract the packaging layer records; compute\r\n * stages add the emitter's `computeFragment` host contract.\r\n */\r\nexport function emitGlslWithOptions(dxbcBytes, options = {})\r\n{\r\n if (!options || typeof options !== \"object\")\r\n {\r\n throw new TypeError(\"CjsWebglFormat: emitGlsl options must be an object\");\r\n }\r\n for (const key of Object.keys(options))\r\n {\r\n if (!EMIT_GLSL_OPTION_KEYS.has(key))\r\n {\r\n throw new TypeError(`CjsWebglFormat: unknown emitGlsl option ${JSON.stringify(key)}`);\r\n }\r\n }\r\n\r\n const profile = {};\r\n for (const key of EMIT_GLSL_PROFILE_KEYS)\r\n {\r\n if (Object.prototype.hasOwnProperty.call(options, key)) profile[key] = options[key];\r\n }\r\n\r\n const emitter = new DxbcGlslEmitter({ profile });\r\n const result = emitter.Emit(dxbcBytes, {\r\n source: options.source,\r\n pairVaryings: options.pairVaryings\r\n });\r\n\r\n // The packed local-light lowering leaves two idioms that must not reach a\r\n // driver: a flag mask round-tripped through a float, and an all-bits mask\r\n // stored as a float and then used for branch control, where 0xFFFFFFFF is a\r\n // NaN. Applied here rather than at a call site so every caller gets them.\r\n if (!options.lightPackedTexture) return result;\r\n\r\n return {\r\n ...result,\r\n source: applyPackedLightFixups(result.source, result.stageName)\r\n };\r\n}\r\n\r\n/**\r\n * Deep-convert a value to plain JSON-compatible data. Typed arrays become\r\n * plain number arrays; Maps/Sets become objects/arrays; class instances\r\n * with toJSON are honoured.\r\n *\r\n * @param {any} value Value to convert.\r\n * @returns {any} Plain data.\r\n */\r\nexport function toJsonValue(value)\r\n{\r\n if (value === null || value === undefined) return value ?? null;\r\n if (typeof value === \"number\" || typeof value === \"string\" || typeof value === \"boolean\") return value;\r\n if (typeof value === \"bigint\") return value.toString();\r\n if (ArrayBuffer.isView(value)) return Array.from(value);\r\n if (Array.isArray(value)) return value.map(toJsonValue);\r\n if (value instanceof Map)\r\n {\r\n const out = {};\r\n for (const [ key, entry ] of value) out[key] = toJsonValue(entry);\r\n return out;\r\n }\r\n if (value instanceof Set) return Array.from(value, toJsonValue);\r\n if (typeof value === \"object\")\r\n {\r\n if (typeof value.toJSON === \"function\") return toJsonValue(value.toJSON());\r\n const out = {};\r\n for (const key of Object.keys(value)) out[key] = toJsonValue(value[key]);\r\n return out;\r\n }\r\n return null;\r\n}\r\n\r\nexport { WebglReadError };\r\n"],"names":["OUTPUT_JSON","DEFAULT_VALUES","Object","freeze","emit","source","VALID_EMITS","Set","OPTION_KEYS","normalizeValues","base","options","readerName","TypeError","key","keys","has","JSON","stringify","values","toBytes","input","Uint8Array","ArrayBuffer","isView","buffer","byteOffset","byteLength","isWebglEffectContainer","looksLikeCarbonEffectContainer","EMIT_GLSL_OPTION_KEYS","EMIT_GLSL_PROFILE_KEYS","emitGlslWithOptions","dxbcBytes","profile","prototype","hasOwnProperty","call","emitter","DxbcGlslEmitter","result","Emit","pairVaryings","lightPackedTexture","applyPackedLightFixups","stageName","toJsonValue","value","undefined","toString","Array","from","isArray","map","Map","out","entry","toJSON"],"mappings":";;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AASO,MAAMA,WAAW,GAAG;MAEdC,cAAc,GAAGC,MAAM,CAACC,MAAM,CAAC;AACxCC,EAAAA,IAAI,EAAEJ,WAAW;AACjBK,EAAAA,MAAM,EAAE;AACZ,CAAC;AAED,MAAMC,WAAW,GAAG,IAAIC,GAAG,CAAC,CAAEP,WAAW,CAAE,CAAC;AAC5C,MAAMQ,WAAW,GAAG,IAAID,GAAG,CAAC,CAAE,MAAM,EAAE,QAAQ,CAAE,CAAC;;AAEjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,eAAeA,CAACC,IAAI,EAAEC,OAAO,GAAG,EAAE,EAAEC,UAAU,GAAG,gBAAgB,EACjF;AACI,EAAA,IAAI,CAACD,OAAO,IAAI,OAAOA,OAAO,KAAK,QAAQ,EAC3C;AACI,IAAA,MAAM,IAAIE,SAAS,CAAC,CAAA,EAAGD,UAAU,6BAA6B,CAAC;AACnE,EAAA;EACA,KAAK,MAAME,GAAG,IAAIZ,MAAM,CAACa,IAAI,CAACJ,OAAO,CAAC,EACtC;AACI,IAAA,IAAI,CAACH,WAAW,CAACQ,GAAG,CAACF,GAAG,CAAC,EACzB;AACI,MAAA,MAAM,IAAID,SAAS,CAAC,CAAA,EAAGD,UAAU,CAAA,iBAAA,EAAoBK,IAAI,CAACC,SAAS,CAACJ,GAAG,CAAC,EAAE,CAAC;AAC/E,IAAA;AACJ,EAAA;AAEA,EAAA,MAAMK,MAAM,GAAG;AAAE,IAAA,GAAGT,IAAI;IAAE,GAAGC;GAAS;EAEtC,IAAI,CAACL,WAAW,CAACU,GAAG,CAACG,MAAM,CAACf,IAAI,CAAC,EACjC;AACI,IAAA,MAAM,IAAIS,SAAS,CAAC,CAAA,EAAGD,UAAU,mBAAmBZ,WAAW,CAAA,OAAA,EAAUiB,IAAI,CAACC,SAAS,CAACC,MAAM,CAACf,IAAI,CAAC,EAAE,CAAC;AAC3G,EAAA;EACA,IAAI,OAAOe,MAAM,CAACd,MAAM,KAAK,QAAQ,IAAI,CAACc,MAAM,CAACd,MAAM,EACvD;AACIc,IAAAA,MAAM,CAACd,MAAM,GAAGJ,cAAc,CAACI,MAAM;AACzC,EAAA;EAEA,OAAO;IACHD,IAAI,EAAEe,MAAM,CAACf,IAAI;IACjBC,MAAM,EAAEc,MAAM,CAACd;GAClB;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASe,OAAOA,CAACC,KAAK,EAC7B;AACI,EAAA,IAAIA,KAAK,YAAYC,UAAU,EAAE,OAAOD,KAAK;AAC7C,EAAA,IAAI,OAAOE,WAAW,KAAK,WAAW,IAAIF,KAAK,YAAYE,WAAW,EAAE,OAAO,IAAID,UAAU,CAACD,KAAK,CAAC;EACpG,IAAIE,WAAW,CAACC,MAAM,CAACH,KAAK,CAAC,EAAE,OAAO,IAAIC,UAAU,CAACD,KAAK,CAACI,MAAM,EAAEJ,KAAK,CAACK,UAAU,EAAEL,KAAK,CAACM,UAAU,CAAC;AACtG,EAAA,MAAM,IAAId,SAAS,CAAC,oGAAoG,CAAC;AAC7H;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASe,sBAAsBA,CAACP,KAAK,EAC5C;EACI,IACA;AACI,IAAA,OAAOQ,8BAA8B,CAACT,OAAO,CAACC,KAAK,CAAC,CAAC;AACzD,EAAA,CAAC,CACD,MACA;AACI,IAAA,OAAO,KAAK;AAChB,EAAA;AACJ;AAEA,MAAMS,qBAAqB,GAAG,IAAIvB,GAAG,CAAC,CAClC,qBAAqB,EACrB,0BAA0B,EAC1B,aAAa,EACb,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,QAAQ,CACX,CAAC;AAEF,MAAMwB,sBAAsB,GAAG,IAAIxB,GAAG,CAAC,CACnC,qBAAqB,EACrB,0BAA0B,EAC1B,aAAa,EACb,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,CACf,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASyB,mBAAmBA,CAACC,SAAS,EAAEtB,OAAO,GAAG,EAAE,EAC3D;AACI,EAAA,IAAI,CAACA,OAAO,IAAI,OAAOA,OAAO,KAAK,QAAQ,EAC3C;AACI,IAAA,MAAM,IAAIE,SAAS,CAAC,oDAAoD,CAAC;AAC7E,EAAA;EACA,KAAK,MAAMC,GAAG,IAAIZ,MAAM,CAACa,IAAI,CAACJ,OAAO,CAAC,EACtC;AACI,IAAA,IAAI,CAACmB,qBAAqB,CAACd,GAAG,CAACF,GAAG,CAAC,EACnC;MACI,MAAM,IAAID,SAAS,CAAC,CAAA,wCAAA,EAA2CI,IAAI,CAACC,SAAS,CAACJ,GAAG,CAAC,CAAA,CAAE,CAAC;AACzF,IAAA;AACJ,EAAA;EAEA,MAAMoB,OAAO,GAAG,EAAE;AAClB,EAAA,KAAK,MAAMpB,GAAG,IAAIiB,sBAAsB,EACxC;IACI,IAAI7B,MAAM,CAACiC,SAAS,CAACC,cAAc,CAACC,IAAI,CAAC1B,OAAO,EAAEG,GAAG,CAAC,EAAEoB,OAAO,CAACpB,GAAG,CAAC,GAAGH,OAAO,CAACG,GAAG,CAAC;AACvF,EAAA;AAEA,EAAA,MAAMwB,OAAO,GAAG,IAAIC,eAAe,CAAC;AAAEL,IAAAA;AAAQ,GAAC,CAAC;AAChD,EAAA,MAAMM,MAAM,GAAGF,OAAO,CAACG,IAAI,CAACR,SAAS,EAAE;IACnC5B,MAAM,EAAEM,OAAO,CAACN,MAAM;IACtBqC,YAAY,EAAE/B,OAAO,CAAC+B;AAC1B,GAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA,EAAA,IAAI,CAAC/B,OAAO,CAACgC,kBAAkB,EAAE,OAAOH,MAAM;EAE9C,OAAO;AACH,IAAA,GAAGA,MAAM;IACTnC,MAAM,EAAEuC,sBAAsB,CAACJ,MAAM,CAACnC,MAAM,EAAEmC,MAAM,CAACK,SAAS;GACjE;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,WAAWA,CAACC,KAAK,EACjC;EACI,IAAIA,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAKC,SAAS,EAAE,OAAOD,KAAK,IAAI,IAAI;AAC/D,EAAA,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,OAAOA,KAAK,KAAK,SAAS,EAAE,OAAOA,KAAK;EACtG,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE,OAAOA,KAAK,CAACE,QAAQ,EAAE;AACtD,EAAA,IAAI1B,WAAW,CAACC,MAAM,CAACuB,KAAK,CAAC,EAAE,OAAOG,KAAK,CAACC,IAAI,CAACJ,KAAK,CAAC;AACvD,EAAA,IAAIG,KAAK,CAACE,OAAO,CAACL,KAAK,CAAC,EAAE,OAAOA,KAAK,CAACM,GAAG,CAACP,WAAW,CAAC;EACvD,IAAIC,KAAK,YAAYO,GAAG,EACxB;IACI,MAAMC,GAAG,GAAG,EAAE;AACd,IAAA,KAAK,MAAM,CAAEzC,GAAG,EAAE0C,KAAK,CAAE,IAAIT,KAAK,EAAEQ,GAAG,CAACzC,GAAG,CAAC,GAAGgC,WAAW,CAACU,KAAK,CAAC;AACjE,IAAA,OAAOD,GAAG;AACd,EAAA;AACA,EAAA,IAAIR,KAAK,YAAYxC,GAAG,EAAE,OAAO2C,KAAK,CAACC,IAAI,CAACJ,KAAK,EAAED,WAAW,CAAC;AAC/D,EAAA,IAAI,OAAOC,KAAK,KAAK,QAAQ,EAC7B;AACI,IAAA,IAAI,OAAOA,KAAK,CAACU,MAAM,KAAK,UAAU,EAAE,OAAOX,WAAW,CAACC,KAAK,CAACU,MAAM,EAAE,CAAC;IAC1E,MAAMF,GAAG,GAAG,EAAE;IACd,KAAK,MAAMzC,GAAG,IAAIZ,MAAM,CAACa,IAAI,CAACgC,KAAK,CAAC,EAAEQ,GAAG,CAACzC,GAAG,CAAC,GAAGgC,WAAW,CAACC,KAAK,CAACjC,GAAG,CAAC,CAAC;AACxE,IAAA,OAAOyC,GAAG;AACd,EAAA;AACA,EAAA,OAAO,IAAI;AACf;;;;"}
|
|
@@ -243,7 +243,16 @@ function readGlslEffectContainer(input, values = {}) {
|
|
|
243
243
|
// match the ambient ones and total for one whose do
|
|
244
244
|
// not - an additive pass writing alpha 0 disappears
|
|
245
245
|
// completely under a src-alpha blend.
|
|
246
|
-
|
|
246
|
+
//
|
|
247
|
+
// `states`, not `renderStates`. Carbon's `Tr2Pass`
|
|
248
|
+
// reserves `renderStates` for the `unsigned int`
|
|
249
|
+
// handle `RegisterRenderStateSetup` hands back
|
|
250
|
+
// (Tr2EffectDescription.h:205), and calls the pairs
|
|
251
|
+
// themselves `states` - as do the WebGPU analysis
|
|
252
|
+
// passes and both of ccpwgl's legacy readers. This
|
|
253
|
+
// path never registers anything, so it carries the
|
|
254
|
+
// list and no handle rather than inventing a number.
|
|
255
|
+
states: pass.renderStates ?? [],
|
|
247
256
|
// The pass's transforms, so a rule can ask whether a
|
|
248
257
|
// description resource was merged away rather than lost.
|
|
249
258
|
transforms
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readGlslEffectContainer.js","sources":["../../../../../src/formats/webgl/core/readGlslEffectContainer.js"],"sourcesContent":["import { CjsCarbonEffectReader } from \"../../../format/carbonEffect/CjsCarbonEffectReader.js\";\nimport { readGlslBackendBlock } from \"./glslBackendBlock.js\";\nimport {\n CARBON_BACKEND_ENGINE_ID,\n peekBackendEngineId\n} from \"../../../format/carbonEffect/backendEngineId.js\";\nimport { hlslShaderStageName } from \"../../hlsl/core/tr2/HlslRenderContextEnum.js\";\nimport { runtimeDescriptionFromCarbon } from \"../../hlsl/core/carbonDescriptionToRuntime.js\";\nimport { HlslEffectBindingManifest } from \"../../hlsl/core/tr2/shader/HlslEffectBindingManifest.js\";\n\n/**\n * Decodes a WebGL effect container into the stage/shader records the\n * completeness rules consume.\n *\n * This exists so the rules run from container bytes alone. The alternative was\n * to hand them the in-memory translation, which works inside `buildEffectPackage`\n * and nowhere else — the validator reads a finished file and has no translation\n * in scope. That would have cost the validator its completeness check while\n * still requiring a decoder to produce the programs it compiles in a browser, so\n * it was strictly more work for strictly less checking.\n *\n * The vocabulary is deliberately the one the rules already speak — `stages` with\n * pass coordinates, `shaders` with source and a translation verdict. The rules\n * are about the translation, not about how it was stored, so retargeting them\n * meant changing where the records come from and nothing about what they mean.\n *\n * **What the wire cannot tell you.** `buildCarbonEffectContainer` stores a body\n * the translator could not lower as its full pass tree with zero-length\n * programs; the *reason* it failed stays in the in-memory build result and is\n * never written. So a shader decoded from bytes reports `ok: false` with\n * \"no program was stored\" and nothing more specific. That is the honest answer:\n * a file on disk does not know why a translation failed months ago. Callers that\n * do know — `buildEffectPackage`, at build time — keep their specific\n * diagnostics by feeding the rules their own records instead.\n */\n\n/** The verdict a stage carrying no stored program gets. */\nconst NO_PROGRAM_REASON = \"no program was stored\";\n\n/**\n * Derives the per-stage binding manifests for one body through the one\n * manifest builder the source path uses.\n *\n * This replaces a hand-built reshape of the wire records into the manifest\n * vocabulary. That copy had already diverged from the real manifest once —\n * `isAutoregister` was silently dropped, making every resource look\n * user-settable — which is the whole argument against a second producer: two\n * hand-maintained spellings of one reflection drift, and the drift is exactly\n * the kind of bug that draws, links and renders black without an error. The\n * record tree now flows through `runtimeDescriptionFromCarbon` — the\n * corpus-proven adapter the runtime read path uses — and\n * `HlslEffectBindingManifest`, so the container read and the build-time\n * package derive their manifests from the same code.\n *\n * No `bytecodeFor` is supplied: program text lives in the shader records this\n * reader emits, so the manifest's `shaderBytecode` stays null rather than\n * duplicating every program into the reflection.\n *\n * @param {object} description Decoded Carbon description record tree.\n * @param {number} version Container data version.\n * @param {string} source Source name for diagnostics.\n * @returns {Map<string, object>} Manifest stage records keyed by\n * `technique.passN.stageName`.\n */\nfunction bodyManifestStages(description, version, source)\n{\n const runtime = runtimeDescriptionFromCarbon(description, {\n effectName: source,\n version\n });\n const manifest = HlslEffectBindingManifest.fromEffectDescription(runtime).toJSON();\n return new Map(manifest.stages.map((stage) => [\n `${stage.techniqueName}.pass${stage.passIndex}.${stage.stageName}`,\n stage\n ]));\n}\n\n/**\n * Decodes one pass's backend block, tolerating a pass that has none.\n *\n * @param {object} pass Decoded pass record.\n * @param {string} passKey Enclosing pass key.\n * @param {string} source Source name for error details.\n * @returns {object} Per-stage backend data, keyed by stage name.\n */\nfunction backendStages(pass, passKey, source)\n{\n if (!pass.backendBlock?.size) return { stages: {}, transforms: [] };\n\n // A block belonging to another backend is not an error here. The container\n // is Carbon-shaped whatever it targets, and loading it must not depend on\n // being able to use its programs - a dx11 container loads and simply cannot\n // be executed by this library. Report no backend data and let prepare fail\n // where the backend actually matters.\n const engineId = peekBackendEngineId(pass.backendBlock.bytes);\n if (engineId !== CARBON_BACKEND_ENGINE_ID.webgl2)\n {\n return { stages: {}, transforms: [], foreignEngineId: engineId };\n }\n\n const block = readGlslBackendBlock(pass.backendBlock.bytes, { layoutKey: passKey, source });\n return { stages: block.stages ?? {}, transforms: block.transforms ?? [] };\n}\n\n/**\n * Decodes container bytes into stage and shader records.\n *\n * Bodies are decoded once each rather than once per permutation row: rows alias\n * onto shared bodies, and a rule that saw the same body 4,096 times would report\n * 4,096 identical incomplete passes.\n *\n * @param {Uint8Array|ArrayBuffer|Buffer|DataView} input Container payload.\n * @param {object} [values] Read values.\n * @param {string} [values.source] Source name, for diagnostics.\n * @returns {{stages:object[], shaders:object[], recordCount:number, bodyCount:number}}\n * Stage graph in the completeness rules' vocabulary.\n */\nexport function readGlslEffectContainer(input, values = {})\n{\n const source = values.source ?? \"memory\";\n const reader = new CjsCarbonEffectReader(input, { source });\n\n const stages = [];\n const shaders = [];\n const bodyKeyByOffset = new Map();\n\n // Every permutation index that resolves to each body.\n //\n // This is the bridge a caller actually needs, and the only one that is\n // sound. `bodyKey` here is this reader's own ordinal spelling; the\n // permutation graph mints `body${N}` for the same body, and the two are not\n // merely spelled differently — the graph dedupes by content (SHA-256 plus\n // byte equality) while this reader dedupes by source-record offset. Those\n // partitions coincide only because the container writer aliases\n // byte-identical bodies onto one offset, which is a property of the writer\n // rather than a contract.\n //\n // So a consumer must never map between the two by string surgery on either\n // spelling, and must not assume the two ordinal sequences agree. It holds a\n // permutation index; this gives it the body directly.\n const permutationIndicesByOffset = new Map();\n\n for (let index = 0; index < reader.records.length; index += 1)\n {\n const { offset } = reader.records[index];\n const seen = permutationIndicesByOffset.get(offset);\n if (seen) seen.push(index);\n else permutationIndicesByOffset.set(offset, [ index ]);\n }\n\n // Distinct program texts share one shader record, so `shaders` counts unique\n // translations the way the chunk package's shader table did. Empty stages are\n // deliberately *not* pooled: each keeps its own record so a report can name\n // every pass that is missing a program rather than one shared \"absent\".\n //\n // The pool key is the program text *and* the backend reflection that came\n // with it, not the text alone. A pooled record carries the bindings and\n // stage inputs of whichever stage was seen first, and\n // `validateShaderRuntimeContract` judges the emitted GLSL against them — so\n // pooling on text alone would let two stages with identical source but\n // different reflection be checked against the wrong metadata, silently. It\n // is unlikely that identical GLSL ever carries different reflection, which\n // is exactly why it would not be noticed.\n const shaderKeyByIdentity = new Map();\n\n for (let index = 0; index < reader.records.length; index += 1)\n {\n const { offset } = reader.records[index];\n if (bodyKeyByOffset.has(offset)) continue;\n\n const bodyKey = `body_${bodyKeyByOffset.size}`;\n bodyKeyByOffset.set(offset, bodyKey);\n\n const description = reader.readDescription(index, { backend: true });\n const manifestStages = bodyManifestStages(description, reader.version, source);\n\n for (const technique of description.techniques)\n {\n const techniqueName = technique.name.value;\n for (const [ passIndex, pass ] of technique.passes.entries())\n {\n const passKey = `${techniqueName}.pass${passIndex}`;\n const { stages: backend, transforms } = backendStages(\n pass,\n passKey,\n source\n );\n\n for (const stage of pass.stages)\n {\n const name = hlslShaderStageName(stage.type);\n const stageKey = `${bodyKey}.${passKey}.${name}`;\n const stageBackend = backend[name] ?? {};\n\n let shaderKey;\n if (stage.shaderData?.size)\n {\n const code = new TextDecoder().decode(stage.shaderData.bytes);\n const identity = `${JSON.stringify([\n stageBackend.bindings ?? [],\n stageBackend.stageInputs ?? [],\n stageBackend.computeFragment ?? null\n ])} ${code}`;\n const pooled = shaderKeyByIdentity.get(identity);\n if (pooled)\n {\n shaderKey = pooled;\n }\n else\n {\n shaderKey = `shader_${shaderKeyByIdentity.size}`;\n shaderKeyByIdentity.set(identity, shaderKey);\n shaders.push({\n key: shaderKey,\n stageName: name,\n source: code,\n hlsl2webgl: { ok: true },\n bindings: stageBackend.bindings ?? [],\n stageInputs: stageBackend.stageInputs ?? [],\n ...(stageBackend.computeFragment\n ? { computeFragment: stageBackend.computeFragment }\n : {})\n });\n }\n }\n else\n {\n shaderKey = `${stageKey}.absent`;\n shaders.push({\n key: shaderKey,\n stageName: name,\n source: \"\",\n hlsl2webgl: { ok: false, reason: NO_PROGRAM_REASON },\n bindings: stageBackend.bindings ?? [],\n stageInputs: stageBackend.stageInputs ?? []\n });\n }\n\n stages.push({\n key: stageKey,\n bodyKey,\n techniqueName,\n passIndex,\n stageName: name,\n stageType: stage.type,\n shaderKey,\n manifest: manifestStages.get(`${passKey}.${name}`) ?? null,\n // The pass's D3D render states, verbatim from the\n // description. They are not reflection and nothing in\n // the GLSL implies them, so a consumer that only reads\n // programs and bindings renders every effect with\n // whatever state the previous draw happened to leave\n // set. That is invisible for an effect whose states\n // match the ambient ones and total for one whose do\n // not - an additive pass writing alpha 0 disappears\n // completely under a src-alpha blend.\n renderStates: pass.renderStates ?? [],\n // The pass's transforms, so a rule can ask whether a\n // description resource was merged away rather than lost.\n transforms\n });\n }\n }\n }\n }\n\n // Ordered by first appearance, matching `bodyKey`'s ordinal.\n const bodies = [];\n for (const [ offset, key ] of bodyKeyByOffset)\n {\n bodies.push({\n key,\n permutationIndices: Object.freeze(permutationIndicesByOffset.get(offset) ?? [])\n });\n }\n\n return {\n stages,\n shaders,\n bodies,\n recordCount: reader.records.length,\n bodyCount: bodyKeyByOffset.size\n };\n}\n\nexport default readGlslEffectContainer;\n"],"names":["NO_PROGRAM_REASON","bodyManifestStages","description","version","source","runtime","runtimeDescriptionFromCarbon","effectName","manifest","HlslEffectBindingManifest","fromEffectDescription","toJSON","Map","stages","map","stage","techniqueName","passIndex","stageName","backendStages","pass","passKey","backendBlock","size","transforms","engineId","peekBackendEngineId","bytes","CARBON_BACKEND_ENGINE_ID","webgl2","foreignEngineId","block","readGlslBackendBlock","layoutKey","readGlslEffectContainer","input","values","reader","CjsCarbonEffectReader","shaders","bodyKeyByOffset","permutationIndicesByOffset","index","records","length","offset","seen","get","push","set","shaderKeyByIdentity","has","bodyKey","readDescription","backend","manifestStages","technique","techniques","name","value","passes","entries","hlslShaderStageName","type","stageKey","stageBackend","shaderKey","shaderData","code","TextDecoder","decode","identity","JSON","stringify","bindings","stageInputs","computeFragment","pooled","key","hlsl2webgl","ok","reason","stageType","renderStates","bodies","permutationIndices","Object","freeze","recordCount","bodyCount"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"readGlslEffectContainer.js","sources":["../../../../../src/formats/webgl/core/readGlslEffectContainer.js"],"sourcesContent":["import { CjsCarbonEffectReader } from \"../../../format/carbonEffect/CjsCarbonEffectReader.js\";\nimport { readGlslBackendBlock } from \"./glslBackendBlock.js\";\nimport {\n CARBON_BACKEND_ENGINE_ID,\n peekBackendEngineId\n} from \"../../../format/carbonEffect/backendEngineId.js\";\nimport { hlslShaderStageName } from \"../../hlsl/core/tr2/HlslRenderContextEnum.js\";\nimport { runtimeDescriptionFromCarbon } from \"../../hlsl/core/carbonDescriptionToRuntime.js\";\nimport { HlslEffectBindingManifest } from \"../../hlsl/core/tr2/shader/HlslEffectBindingManifest.js\";\n\n/**\n * Decodes a WebGL effect container into the stage/shader records the\n * completeness rules consume.\n *\n * This exists so the rules run from container bytes alone. The alternative was\n * to hand them the in-memory translation, which works inside `buildEffectPackage`\n * and nowhere else — the validator reads a finished file and has no translation\n * in scope. That would have cost the validator its completeness check while\n * still requiring a decoder to produce the programs it compiles in a browser, so\n * it was strictly more work for strictly less checking.\n *\n * The vocabulary is deliberately the one the rules already speak — `stages` with\n * pass coordinates, `shaders` with source and a translation verdict. The rules\n * are about the translation, not about how it was stored, so retargeting them\n * meant changing where the records come from and nothing about what they mean.\n *\n * **What the wire cannot tell you.** `buildCarbonEffectContainer` stores a body\n * the translator could not lower as its full pass tree with zero-length\n * programs; the *reason* it failed stays in the in-memory build result and is\n * never written. So a shader decoded from bytes reports `ok: false` with\n * \"no program was stored\" and nothing more specific. That is the honest answer:\n * a file on disk does not know why a translation failed months ago. Callers that\n * do know — `buildEffectPackage`, at build time — keep their specific\n * diagnostics by feeding the rules their own records instead.\n */\n\n/** The verdict a stage carrying no stored program gets. */\nconst NO_PROGRAM_REASON = \"no program was stored\";\n\n/**\n * Derives the per-stage binding manifests for one body through the one\n * manifest builder the source path uses.\n *\n * This replaces a hand-built reshape of the wire records into the manifest\n * vocabulary. That copy had already diverged from the real manifest once —\n * `isAutoregister` was silently dropped, making every resource look\n * user-settable — which is the whole argument against a second producer: two\n * hand-maintained spellings of one reflection drift, and the drift is exactly\n * the kind of bug that draws, links and renders black without an error. The\n * record tree now flows through `runtimeDescriptionFromCarbon` — the\n * corpus-proven adapter the runtime read path uses — and\n * `HlslEffectBindingManifest`, so the container read and the build-time\n * package derive their manifests from the same code.\n *\n * No `bytecodeFor` is supplied: program text lives in the shader records this\n * reader emits, so the manifest's `shaderBytecode` stays null rather than\n * duplicating every program into the reflection.\n *\n * @param {object} description Decoded Carbon description record tree.\n * @param {number} version Container data version.\n * @param {string} source Source name for diagnostics.\n * @returns {Map<string, object>} Manifest stage records keyed by\n * `technique.passN.stageName`.\n */\nfunction bodyManifestStages(description, version, source)\n{\n const runtime = runtimeDescriptionFromCarbon(description, {\n effectName: source,\n version\n });\n const manifest = HlslEffectBindingManifest.fromEffectDescription(runtime).toJSON();\n return new Map(manifest.stages.map((stage) => [\n `${stage.techniqueName}.pass${stage.passIndex}.${stage.stageName}`,\n stage\n ]));\n}\n\n/**\n * Decodes one pass's backend block, tolerating a pass that has none.\n *\n * @param {object} pass Decoded pass record.\n * @param {string} passKey Enclosing pass key.\n * @param {string} source Source name for error details.\n * @returns {object} Per-stage backend data, keyed by stage name.\n */\nfunction backendStages(pass, passKey, source)\n{\n if (!pass.backendBlock?.size) return { stages: {}, transforms: [] };\n\n // A block belonging to another backend is not an error here. The container\n // is Carbon-shaped whatever it targets, and loading it must not depend on\n // being able to use its programs - a dx11 container loads and simply cannot\n // be executed by this library. Report no backend data and let prepare fail\n // where the backend actually matters.\n const engineId = peekBackendEngineId(pass.backendBlock.bytes);\n if (engineId !== CARBON_BACKEND_ENGINE_ID.webgl2)\n {\n return { stages: {}, transforms: [], foreignEngineId: engineId };\n }\n\n const block = readGlslBackendBlock(pass.backendBlock.bytes, { layoutKey: passKey, source });\n return { stages: block.stages ?? {}, transforms: block.transforms ?? [] };\n}\n\n/**\n * Decodes container bytes into stage and shader records.\n *\n * Bodies are decoded once each rather than once per permutation row: rows alias\n * onto shared bodies, and a rule that saw the same body 4,096 times would report\n * 4,096 identical incomplete passes.\n *\n * @param {Uint8Array|ArrayBuffer|Buffer|DataView} input Container payload.\n * @param {object} [values] Read values.\n * @param {string} [values.source] Source name, for diagnostics.\n * @returns {{stages:object[], shaders:object[], recordCount:number, bodyCount:number}}\n * Stage graph in the completeness rules' vocabulary.\n */\nexport function readGlslEffectContainer(input, values = {})\n{\n const source = values.source ?? \"memory\";\n const reader = new CjsCarbonEffectReader(input, { source });\n\n const stages = [];\n const shaders = [];\n const bodyKeyByOffset = new Map();\n\n // Every permutation index that resolves to each body.\n //\n // This is the bridge a caller actually needs, and the only one that is\n // sound. `bodyKey` here is this reader's own ordinal spelling; the\n // permutation graph mints `body${N}` for the same body, and the two are not\n // merely spelled differently — the graph dedupes by content (SHA-256 plus\n // byte equality) while this reader dedupes by source-record offset. Those\n // partitions coincide only because the container writer aliases\n // byte-identical bodies onto one offset, which is a property of the writer\n // rather than a contract.\n //\n // So a consumer must never map between the two by string surgery on either\n // spelling, and must not assume the two ordinal sequences agree. It holds a\n // permutation index; this gives it the body directly.\n const permutationIndicesByOffset = new Map();\n\n for (let index = 0; index < reader.records.length; index += 1)\n {\n const { offset } = reader.records[index];\n const seen = permutationIndicesByOffset.get(offset);\n if (seen) seen.push(index);\n else permutationIndicesByOffset.set(offset, [ index ]);\n }\n\n // Distinct program texts share one shader record, so `shaders` counts unique\n // translations the way the chunk package's shader table did. Empty stages are\n // deliberately *not* pooled: each keeps its own record so a report can name\n // every pass that is missing a program rather than one shared \"absent\".\n //\n // The pool key is the program text *and* the backend reflection that came\n // with it, not the text alone. A pooled record carries the bindings and\n // stage inputs of whichever stage was seen first, and\n // `validateShaderRuntimeContract` judges the emitted GLSL against them — so\n // pooling on text alone would let two stages with identical source but\n // different reflection be checked against the wrong metadata, silently. It\n // is unlikely that identical GLSL ever carries different reflection, which\n // is exactly why it would not be noticed.\n const shaderKeyByIdentity = new Map();\n\n for (let index = 0; index < reader.records.length; index += 1)\n {\n const { offset } = reader.records[index];\n if (bodyKeyByOffset.has(offset)) continue;\n\n const bodyKey = `body_${bodyKeyByOffset.size}`;\n bodyKeyByOffset.set(offset, bodyKey);\n\n const description = reader.readDescription(index, { backend: true });\n const manifestStages = bodyManifestStages(description, reader.version, source);\n\n for (const technique of description.techniques)\n {\n const techniqueName = technique.name.value;\n for (const [ passIndex, pass ] of technique.passes.entries())\n {\n const passKey = `${techniqueName}.pass${passIndex}`;\n const { stages: backend, transforms } = backendStages(\n pass,\n passKey,\n source\n );\n\n for (const stage of pass.stages)\n {\n const name = hlslShaderStageName(stage.type);\n const stageKey = `${bodyKey}.${passKey}.${name}`;\n const stageBackend = backend[name] ?? {};\n\n let shaderKey;\n if (stage.shaderData?.size)\n {\n const code = new TextDecoder().decode(stage.shaderData.bytes);\n const identity = `${JSON.stringify([\n stageBackend.bindings ?? [],\n stageBackend.stageInputs ?? [],\n stageBackend.computeFragment ?? null\n ])} ${code}`;\n const pooled = shaderKeyByIdentity.get(identity);\n if (pooled)\n {\n shaderKey = pooled;\n }\n else\n {\n shaderKey = `shader_${shaderKeyByIdentity.size}`;\n shaderKeyByIdentity.set(identity, shaderKey);\n shaders.push({\n key: shaderKey,\n stageName: name,\n source: code,\n hlsl2webgl: { ok: true },\n bindings: stageBackend.bindings ?? [],\n stageInputs: stageBackend.stageInputs ?? [],\n ...(stageBackend.computeFragment\n ? { computeFragment: stageBackend.computeFragment }\n : {})\n });\n }\n }\n else\n {\n shaderKey = `${stageKey}.absent`;\n shaders.push({\n key: shaderKey,\n stageName: name,\n source: \"\",\n hlsl2webgl: { ok: false, reason: NO_PROGRAM_REASON },\n bindings: stageBackend.bindings ?? [],\n stageInputs: stageBackend.stageInputs ?? []\n });\n }\n\n stages.push({\n key: stageKey,\n bodyKey,\n techniqueName,\n passIndex,\n stageName: name,\n stageType: stage.type,\n shaderKey,\n manifest: manifestStages.get(`${passKey}.${name}`) ?? null,\n // The pass's D3D render states, verbatim from the\n // description. They are not reflection and nothing in\n // the GLSL implies them, so a consumer that only reads\n // programs and bindings renders every effect with\n // whatever state the previous draw happened to leave\n // set. That is invisible for an effect whose states\n // match the ambient ones and total for one whose do\n // not - an additive pass writing alpha 0 disappears\n // completely under a src-alpha blend.\n //\n // `states`, not `renderStates`. Carbon's `Tr2Pass`\n // reserves `renderStates` for the `unsigned int`\n // handle `RegisterRenderStateSetup` hands back\n // (Tr2EffectDescription.h:205), and calls the pairs\n // themselves `states` - as do the WebGPU analysis\n // passes and both of ccpwgl's legacy readers. This\n // path never registers anything, so it carries the\n // list and no handle rather than inventing a number.\n states: pass.renderStates ?? [],\n // The pass's transforms, so a rule can ask whether a\n // description resource was merged away rather than lost.\n transforms\n });\n }\n }\n }\n }\n\n // Ordered by first appearance, matching `bodyKey`'s ordinal.\n const bodies = [];\n for (const [ offset, key ] of bodyKeyByOffset)\n {\n bodies.push({\n key,\n permutationIndices: Object.freeze(permutationIndicesByOffset.get(offset) ?? [])\n });\n }\n\n return {\n stages,\n shaders,\n bodies,\n recordCount: reader.records.length,\n bodyCount: bodyKeyByOffset.size\n };\n}\n\nexport default readGlslEffectContainer;\n"],"names":["NO_PROGRAM_REASON","bodyManifestStages","description","version","source","runtime","runtimeDescriptionFromCarbon","effectName","manifest","HlslEffectBindingManifest","fromEffectDescription","toJSON","Map","stages","map","stage","techniqueName","passIndex","stageName","backendStages","pass","passKey","backendBlock","size","transforms","engineId","peekBackendEngineId","bytes","CARBON_BACKEND_ENGINE_ID","webgl2","foreignEngineId","block","readGlslBackendBlock","layoutKey","readGlslEffectContainer","input","values","reader","CjsCarbonEffectReader","shaders","bodyKeyByOffset","permutationIndicesByOffset","index","records","length","offset","seen","get","push","set","shaderKeyByIdentity","has","bodyKey","readDescription","backend","manifestStages","technique","techniques","name","value","passes","entries","hlslShaderStageName","type","stageKey","stageBackend","shaderKey","shaderData","code","TextDecoder","decode","identity","JSON","stringify","bindings","stageInputs","computeFragment","pooled","key","hlsl2webgl","ok","reason","stageType","states","renderStates","bodies","permutationIndices","Object","freeze","recordCount","bodyCount"],"mappings":"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"}
|