@carbonenginejs/runtime 0.1.0-alpha.1 → 0.1.0-alpha.2
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/global/schema/CjsSchema.js +20 -2
- package/dist/global/schema/CjsSchema.js.map +1 -1
- package/dist/global/schema/hydration.js +14 -0
- package/dist/global/schema/hydration.js.map +1 -1
- package/dist/resource/formats/webgl/core/glsl/DxbcGlslEmitter.js +17 -5
- package/dist/resource/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
- package/dist/resource/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js +12 -3
- package/dist/resource/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js.map +1 -1
- package/docs/resource/formats/webgpu/reference/wgsl-compatibility.md +54 -85
- package/docs/trinityal/reference/classes/dropped.md +11 -1
- package/package.json +1 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { CjsSchema } from './CjsSchema.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Hydration adapter seam - the population contract for readers that build
|
|
3
5
|
* runtime objects incrementally (black/red). The ordering guarantee:
|
|
@@ -24,8 +26,16 @@
|
|
|
24
26
|
* SetValues is called directly rather than through CjsSchema.setValues so a
|
|
25
27
|
* reader works with only the schema layer loaded; the two are the same path
|
|
26
28
|
* for every class that has the method.
|
|
29
|
+
*
|
|
30
|
+
* A REGISTERED class without SetValues - one that no longer extends CjsModel -
|
|
31
|
+
* is still a resolved class, so it populates through CjsSchema.setValues, which
|
|
32
|
+
* answers without the model layer. Only an unregistered carrier (the reader's
|
|
33
|
+
* `{ _sourceClassName }` fallback) takes raw assignment. Without this middle
|
|
34
|
+
* arm, taking a class off the base would silently drop it to Object.assign:
|
|
35
|
+
* no coercion, no writability gate, no settle.
|
|
27
36
|
*/
|
|
28
37
|
|
|
38
|
+
|
|
29
39
|
/**
|
|
30
40
|
* Resolves a normalized adapter from hydration options. The returned object
|
|
31
41
|
* always exposes construct/applyValues/finalize with the documented defaults.
|
|
@@ -47,6 +57,10 @@ function resolveHydrationAdapter(options = {}) {
|
|
|
47
57
|
instance.SetValues(values, ctx?.options);
|
|
48
58
|
return instance;
|
|
49
59
|
}
|
|
60
|
+
if (instance && CjsSchema.getClassName(instance.constructor)) {
|
|
61
|
+
CjsSchema.setValues(instance, values, ctx?.options);
|
|
62
|
+
return instance;
|
|
63
|
+
}
|
|
50
64
|
return Object.assign(instance, values);
|
|
51
65
|
},
|
|
52
66
|
finalize(instance, ctx) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hydration.js","sources":["../../../../src/global/schema/hydration.js"],"sourcesContent":["/**\n * Hydration adapter seam - the population contract for readers that build\n * runtime objects incrementally (black/red). The ordering guarantee:\n *\n * 1. construct - build every instance (register refs before values, so\n * cycles/back-references resolve)\n * 2. applyValues - apply each node's field values\n * 3. finalize - run once per instance AFTER the whole graph is built,\n * so references are already resolved\n *\n * DEFAULTS (operator ruling, 2026-09-05; resource-population.md owns the\n * decision): a resolved class is populated through its own validated setter -\n * \"if someone is using Object.assign, they probably should be using\n * SetValues\" - and a class-owned Initialize runs once post-graph, which is\n * the incremental-reader counterpart of the reader+IInitialize handshake\n * Blue performs and CjsModel.from performs for whole-bag JSON. Plain\n * fallback carriers (unresolved kinds) keep raw assignment: that IS their\n * contract, not a bypass.\n *\n * The single escape hatch is `options.adapter`, per-hook optional. The\n * per-kind adapters map and the hydrationAdapter alias are gone - they had\n * zero consumers. Callers wanting raw assignment pass their own adapter.\n *\n * SetValues is called directly rather than through CjsSchema.setValues so a\n * reader works with only the schema layer loaded; the two are the same path\n * for every class that has the method.\n */\n\n/**\n * Resolves a normalized adapter from hydration options. The returned object\n * always exposes construct/applyValues/finalize with the documented defaults.\n *\n * @param {Object} [options]\n * @param {Object} [options.adapter] Per-hook overrides: construct/applyValues/finalize.\n * @returns {{ construct: Function, applyValues: Function, finalize: Function }}\n */\nexport function resolveHydrationAdapter(options = {})\n{\n const custom = options.adapter || null;\n\n return {\n construct(kind, ctx)\n {\n if (custom && typeof custom.construct === \"function\") return custom.construct(kind, ctx);\n return undefined;\n },\n applyValues(instance, values, ctx)\n {\n if (custom && typeof custom.applyValues === \"function\") return custom.applyValues(instance, values, ctx);\n if (instance && typeof instance.SetValues === \"function\")\n {\n instance.SetValues(values, ctx?.options);\n return instance;\n }\n return Object.assign(instance, values);\n },\n finalize(instance, ctx)\n {\n if (custom && typeof custom.finalize === \"function\")\n {\n custom.finalize(instance, ctx);\n return;\n }\n if (instance && typeof instance.Initialize === \"function\") instance.Initialize();\n }\n };\n}\n"],"names":["resolveHydrationAdapter","options","custom","adapter","construct","kind","ctx","undefined","applyValues","instance","values","SetValues","Object","assign","finalize","Initialize"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA
|
|
1
|
+
{"version":3,"file":"hydration.js","sources":["../../../../src/global/schema/hydration.js"],"sourcesContent":["/**\n * Hydration adapter seam - the population contract for readers that build\n * runtime objects incrementally (black/red). The ordering guarantee:\n *\n * 1. construct - build every instance (register refs before values, so\n * cycles/back-references resolve)\n * 2. applyValues - apply each node's field values\n * 3. finalize - run once per instance AFTER the whole graph is built,\n * so references are already resolved\n *\n * DEFAULTS (operator ruling, 2026-09-05; resource-population.md owns the\n * decision): a resolved class is populated through its own validated setter -\n * \"if someone is using Object.assign, they probably should be using\n * SetValues\" - and a class-owned Initialize runs once post-graph, which is\n * the incremental-reader counterpart of the reader+IInitialize handshake\n * Blue performs and CjsModel.from performs for whole-bag JSON. Plain\n * fallback carriers (unresolved kinds) keep raw assignment: that IS their\n * contract, not a bypass.\n *\n * The single escape hatch is `options.adapter`, per-hook optional. The\n * per-kind adapters map and the hydrationAdapter alias are gone - they had\n * zero consumers. Callers wanting raw assignment pass their own adapter.\n *\n * SetValues is called directly rather than through CjsSchema.setValues so a\n * reader works with only the schema layer loaded; the two are the same path\n * for every class that has the method.\n *\n * A REGISTERED class without SetValues - one that no longer extends CjsModel -\n * is still a resolved class, so it populates through CjsSchema.setValues, which\n * answers without the model layer. Only an unregistered carrier (the reader's\n * `{ _sourceClassName }` fallback) takes raw assignment. Without this middle\n * arm, taking a class off the base would silently drop it to Object.assign:\n * no coercion, no writability gate, no settle.\n */\n\nimport { CjsSchema } from \"./CjsSchema.js\";\n\n/**\n * Resolves a normalized adapter from hydration options. The returned object\n * always exposes construct/applyValues/finalize with the documented defaults.\n *\n * @param {Object} [options]\n * @param {Object} [options.adapter] Per-hook overrides: construct/applyValues/finalize.\n * @returns {{ construct: Function, applyValues: Function, finalize: Function }}\n */\nexport function resolveHydrationAdapter(options = {})\n{\n const custom = options.adapter || null;\n\n return {\n construct(kind, ctx)\n {\n if (custom && typeof custom.construct === \"function\") return custom.construct(kind, ctx);\n return undefined;\n },\n applyValues(instance, values, ctx)\n {\n if (custom && typeof custom.applyValues === \"function\") return custom.applyValues(instance, values, ctx);\n if (instance && typeof instance.SetValues === \"function\")\n {\n instance.SetValues(values, ctx?.options);\n return instance;\n }\n if (instance && CjsSchema.getClassName(instance.constructor))\n {\n CjsSchema.setValues(instance, values, ctx?.options);\n return instance;\n }\n return Object.assign(instance, values);\n },\n finalize(instance, ctx)\n {\n if (custom && typeof custom.finalize === \"function\")\n {\n custom.finalize(instance, ctx);\n return;\n }\n if (instance && typeof instance.Initialize === \"function\") instance.Initialize();\n }\n };\n}\n"],"names":["resolveHydrationAdapter","options","custom","adapter","construct","kind","ctx","undefined","applyValues","instance","values","SetValues","CjsSchema","getClassName","constructor","setValues","Object","assign","finalize","Initialize"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,uBAAuBA,CAACC,OAAO,GAAG,EAAE,EACpD;AACI,EAAA,MAAMC,MAAM,GAAGD,OAAO,CAACE,OAAO,IAAI,IAAI;EAEtC,OAAO;AACHC,IAAAA,SAASA,CAACC,IAAI,EAAEC,GAAG,EACnB;AACI,MAAA,IAAIJ,MAAM,IAAI,OAAOA,MAAM,CAACE,SAAS,KAAK,UAAU,EAAE,OAAOF,MAAM,CAACE,SAAS,CAACC,IAAI,EAAEC,GAAG,CAAC;AACxF,MAAA,OAAOC,SAAS;IACpB,CAAC;AACDC,IAAAA,WAAWA,CAACC,QAAQ,EAAEC,MAAM,EAAEJ,GAAG,EACjC;AACI,MAAA,IAAIJ,MAAM,IAAI,OAAOA,MAAM,CAACM,WAAW,KAAK,UAAU,EAAE,OAAON,MAAM,CAACM,WAAW,CAACC,QAAQ,EAAEC,MAAM,EAAEJ,GAAG,CAAC;MACxG,IAAIG,QAAQ,IAAI,OAAOA,QAAQ,CAACE,SAAS,KAAK,UAAU,EACxD;QACIF,QAAQ,CAACE,SAAS,CAACD,MAAM,EAAEJ,GAAG,EAAEL,OAAO,CAAC;AACxC,QAAA,OAAOQ,QAAQ;AACnB,MAAA;MACA,IAAIA,QAAQ,IAAIG,SAAS,CAACC,YAAY,CAACJ,QAAQ,CAACK,WAAW,CAAC,EAC5D;QACIF,SAAS,CAACG,SAAS,CAACN,QAAQ,EAAEC,MAAM,EAAEJ,GAAG,EAAEL,OAAO,CAAC;AACnD,QAAA,OAAOQ,QAAQ;AACnB,MAAA;AACA,MAAA,OAAOO,MAAM,CAACC,MAAM,CAACR,QAAQ,EAAEC,MAAM,CAAC;IAC1C,CAAC;AACDQ,IAAAA,QAAQA,CAACT,QAAQ,EAAEH,GAAG,EACtB;MACI,IAAIJ,MAAM,IAAI,OAAOA,MAAM,CAACgB,QAAQ,KAAK,UAAU,EACnD;AACIhB,QAAAA,MAAM,CAACgB,QAAQ,CAACT,QAAQ,EAAEH,GAAG,CAAC;AAC9B,QAAA;AACJ,MAAA;AACA,MAAA,IAAIG,QAAQ,IAAI,OAAOA,QAAQ,CAACU,UAAU,KAAK,UAAU,EAAEV,QAAQ,CAACU,UAAU,EAAE;AACpF,IAAA;GACH;AACL;;;;"}
|
|
@@ -395,13 +395,23 @@ class DxbcGlslEmitter {
|
|
|
395
395
|
this._analyzeUavStores(state);
|
|
396
396
|
}
|
|
397
397
|
state.integerVertexInputs = new Map();
|
|
398
|
+
// Register -> GLSL integer built-in (`gl_VertexID`/`gl_InstanceID`) for
|
|
399
|
+
// system-value inputs; filled by _declareSystemInput.
|
|
400
|
+
state.systemIntegerInputs = new Map();
|
|
401
|
+
// Integer companions for temporaries. Small integers held as float bit
|
|
402
|
+
// patterns are denormals, and ANGLE/D3D11 hardware does not preserve
|
|
403
|
+
// them in float storage: a vertex-id corner index `r0.x = uintBitsToFloat(id & 3u)`
|
|
404
|
+
// reads back 0 for ids 1..3, collapsing every quad (plane sets, the sprite
|
|
405
|
+
// pool). Packed-light shaders need the same companions for their words.
|
|
406
|
+
state.integerTemps = !!state.lightPackedTexture || state.decoder.instructions.some(instruction => (instruction.opcodeName === "dcl_input_sgv" || instruction.opcodeName === "dcl_input_ps_sgv") && (instruction.declaration?.systemValueName === "vertex_id" || instruction.declaration?.systemValueName === "instance_id"));
|
|
398
407
|
state.formatter = new DxbcGlslOperandFormatter({
|
|
399
408
|
// Populated during vertex-input declaration (the declaration loop
|
|
400
409
|
// runs before any body emission, so the map is complete before the
|
|
401
410
|
// first operand is formatted). Integer reads of these registers
|
|
402
411
|
// value-convert instead of bitcast - see _declareVertexInput.
|
|
403
412
|
integerInputs: state.integerVertexInputs,
|
|
404
|
-
integerTemps:
|
|
413
|
+
integerTemps: state.integerTemps,
|
|
414
|
+
systemIntegerInputs: state.systemIntegerInputs,
|
|
405
415
|
componentMap: operand => {
|
|
406
416
|
if (operand.type === 1) return state.inputMasks.get(operand.registerIndex) || null;
|
|
407
417
|
if (operand.type === 2) return state.outputMasks.get(operand.registerIndex) || null;
|
|
@@ -1109,7 +1119,7 @@ class DxbcGlslEmitter {
|
|
|
1109
1119
|
case "dcl_temps":
|
|
1110
1120
|
for (let index = 0; index < declaration.tempCount; index += 1) {
|
|
1111
1121
|
state.declarationLines.push(`vec4 r${index};`);
|
|
1112
|
-
if (state.
|
|
1122
|
+
if (state.integerTemps) state.declarationLines.push(`uvec4 cjsBitsR${index};`);
|
|
1113
1123
|
}
|
|
1114
1124
|
break;
|
|
1115
1125
|
case "dcl_indexable_temp":
|
|
@@ -1515,9 +1525,11 @@ class DxbcGlslEmitter {
|
|
|
1515
1525
|
break;
|
|
1516
1526
|
case "vertex_id":
|
|
1517
1527
|
state.inputNames.set(register, "vec4(intBitsToFloat(gl_VertexID))");
|
|
1528
|
+
state.systemIntegerInputs.set(register, "gl_VertexID");
|
|
1518
1529
|
break;
|
|
1519
1530
|
case "instance_id":
|
|
1520
1531
|
state.inputNames.set(register, "vec4(intBitsToFloat(gl_InstanceID))");
|
|
1532
|
+
state.systemIntegerInputs.set(register, "gl_InstanceID");
|
|
1521
1533
|
break;
|
|
1522
1534
|
default:
|
|
1523
1535
|
throw new WebglReadError("System-generated input is not supported by the WebGL2 emitter", {
|
|
@@ -1759,7 +1771,7 @@ class DxbcGlslEmitter {
|
|
|
1759
1771
|
// Centralize writes here because several lowerings emit lane writes
|
|
1760
1772
|
// directly rather than going through _assign. This is per assignment,
|
|
1761
1773
|
// not a shader/register-number pattern or a control-flow dataflow guess.
|
|
1762
|
-
const assignment = state.
|
|
1774
|
+
const assignment = state.integerTemps && /^(r(\d+)(?:\.[xyzw]+)?) = ([\s\S]+);$/.exec(text);
|
|
1763
1775
|
if (assignment) {
|
|
1764
1776
|
const [, target, index, value] = assignment;
|
|
1765
1777
|
const suffix = target.slice(`r${index}`.length);
|
|
@@ -2128,7 +2140,7 @@ class DxbcGlslEmitter {
|
|
|
2128
2140
|
} = this._destMask(state, instruction);
|
|
2129
2141
|
if (!target) return;
|
|
2130
2142
|
const aliases = instruction.operands.slice(1).some(operand => operand.type === destOperand.type && operand.registerIndex === destOperand.registerIndex);
|
|
2131
|
-
const rawMove =
|
|
2143
|
+
const rawMove = state.integerTemps && destOperand.type === 0;
|
|
2132
2144
|
if (aliases) {
|
|
2133
2145
|
this._line(state, "{");
|
|
2134
2146
|
state.indent += 1;
|
|
@@ -2503,7 +2515,7 @@ DxbcGlslEmitter.LOWERINGS = {
|
|
|
2503
2515
|
const {
|
|
2504
2516
|
mask
|
|
2505
2517
|
} = this._destMask(state, instruction);
|
|
2506
|
-
if (state.
|
|
2518
|
+
if (state.integerTemps && instruction.operands[0].type === 0 && !instruction.saturate && !["neg", "abs", "absneg"].includes(instruction.operands[1].modifierName)) {
|
|
2507
2519
|
const raw = this._vecArg(state, instruction.operands[1], mask, "uint");
|
|
2508
2520
|
this._assign(state, instruction, `uintBitsToFloat(${raw})`);
|
|
2509
2521
|
return;
|