@carbonenginejs/runtime 0.1.0-alpha.1 → 0.1.0-alpha.3
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/model/CjsModel.js +3 -1
- package/dist/global/model/CjsModel.js.map +1 -1
- package/dist/global/model/document/CjsDocumentHydrator.js +5 -1
- package/dist/global/model/document/CjsDocumentHydrator.js.map +1 -1
- package/dist/global/schema/CjsSchema.js +100 -2
- package/dist/global/schema/CjsSchema.js.map +1 -1
- package/dist/global/schema/hydration.js +16 -0
- package/dist/global/schema/hydration.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/resource/CjsResMan.js +177 -4
- package/dist/resource/CjsResMan.js.map +1 -1
- package/dist/resource/format/CjsBlueReader.js +8 -1
- package/dist/resource/format/CjsBlueReader.js.map +1 -1
- package/dist/resource/formats/webgl/core/glsl/DxbcGlslEmitter.js +23 -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/dist/resource/index.js +2 -0
- package/dist/resource/index.js.map +1 -1
- package/dist/resource/texture/SolidColorTextureConstructor.js +46 -0
- package/dist/resource/texture/SolidColorTextureConstructor.js.map +1 -0
- package/dist/resource/texture/TriTextureRes.js +43 -0
- package/dist/resource/texture/TriTextureRes.js.map +1 -1
- package/dist/resource/texture/index.js +2 -0
- package/dist/resource/texture/index.js.map +1 -1
- package/dist/resource/texture/solidColorTexture.js +111 -0
- package/dist/resource/texture/solidColorTexture.js.map +1 -0
- package/dist/trinity/eve/attachment/decal/EveSpaceObjectDecal.js +19 -8
- package/dist/trinity/eve/attachment/decal/EveSpaceObjectDecal.js.map +1 -1
- package/dist/trinity/eve/child/EveChildMesh.js +17 -3
- package/dist/trinity/eve/child/EveChildMesh.js.map +1 -1
- package/dist/trinity/eve/locator/EveLocatorSets.js +12 -3
- package/dist/trinity/eve/locator/EveLocatorSets.js.map +1 -1
- package/dist/trinity/eve/spaceObject/EveSpaceObject2.js +15 -2
- package/dist/trinity/eve/spaceObject/EveSpaceObject2.js.map +1 -1
- package/dist/trinity/eve/spaceObject/IEveSpaceObject2ParentData.js +44 -52
- package/dist/trinity/eve/spaceObject/IEveSpaceObject2ParentData.js.map +1 -1
- package/docs/resource/concepts/resource-lifecycle.md +10 -8
- package/docs/resource/formats/geometry-interchange.md +50 -0
- package/docs/resource/formats/webgl/decl-io.md +241 -397
- package/docs/resource/formats/webgl/memory-structured.md +91 -128
- package/docs/resource/formats/webgl/texture-sample.md +306 -469
- package/docs/resource/formats/webgpu/reference/wgsl-compatibility.md +54 -85
- package/docs/resource/reference/classes/texture.md +11 -1
- package/docs/resource/reference/motherlode-cache.md +24 -11
- package/docs/resource/reference/queues.md +23 -1
- package/docs/trinityal/reference/classes/dropped.md +11 -1
- package/package.json +1 -1
|
@@ -474,108 +474,65 @@ the consumer-name qualification above.
|
|
|
474
474
|
---
|
|
475
475
|
|
|
476
476
|
## `dcl_input` (11726)
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
lowering
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
**Edge cases — the uvec/ivec attribute problem (required deviation, highest-priority
|
|
538
|
-
item in this family)**: stock HLSLcc, run as designed, declares integer-semantic
|
|
539
|
-
vertex inputs with their true GLSL integer vector type, e.g. `in uvec4
|
|
540
|
-
in_BLENDINDICES0;` for a `BLENDINDICES` stream reflected as `UINT32` component type
|
|
541
|
-
(`DeclareInput`, `270-274`). **This project's runtime (ccpwgl) binds all mesh
|
|
542
|
-
attribute channels, including blend indices, as float vertex attributes via
|
|
543
|
-
`gl.vertexAttribPointer` (not `vertexAttribIPointer`)** — a real `uvec4 in_...`
|
|
544
|
-
declaration either fails to link against that float-typed buffer binding, or links
|
|
545
|
-
but silently produces garbage/invisible geometry
|
|
546
|
-
(`028-carbonwebgl-skinned-blend-index-abi-lowering.md`: "Raw Carbon WebGL validation can link
|
|
547
|
-
integer attributes, but ccpwgl runtime binding can still fail or produce invisible
|
|
548
|
-
geometry if the source reaches compile as `uvec4`."). The proven, validated fix
|
|
549
|
-
(`028-...md`; `TRANSPILING-GAPS.md` "Ranked helper action plan" documents the general
|
|
550
|
-
version of this class of bug): **lower every integer-component-type `dcl_input`
|
|
551
|
-
vertex attribute to its float-vector equivalent at declaration time** —
|
|
552
|
-
```glsl
|
|
553
|
-
in vec4 in_BLENDINDICES0; // not uvec4
|
|
554
|
-
```
|
|
555
|
-
and bitcast at every *use* site instead: any instruction reading `in_BLENDINDICES0`
|
|
556
|
-
as an index wraps it in `floatBitsToUint(in_BLENDINDICES0)` (or, if the actual buffer
|
|
557
|
-
data was uploaded as plain float index values rather than bit-pattern-encoded uints —
|
|
558
|
-
verify per-attribute — a plain `uint(in_BLENDINDICES0.x)` truncating conversion
|
|
559
|
-
instead of a bitcast; the Carbon WebGL lowering evidence describes casting at use sites but
|
|
560
|
-
does not pin down which of these two forms every producer used, see Confidence
|
|
561
|
-
below). This is the **general form** of the family-level "every register is a float
|
|
562
|
-
vec4" convention applied specifically to `dcl_input`: unlike the `r#` temp file
|
|
563
|
-
(where float-only storage is this project's own choice), for vertex attributes it is
|
|
564
|
-
required by a concrete runtime constraint (float-only `vertexAttribPointer` binding),
|
|
565
|
-
proven necessary by regression (skinned geometry disappearing) and proven sufficient
|
|
566
|
-
(336/336 and 240/240 WebGL2 programs pass after the rewrite) in the corpus evidence
|
|
567
|
-
cited above.
|
|
568
|
-
|
|
569
|
-
**WebGL2 notes**: GLSL ES 3.00 does support genuine integer vertex attributes
|
|
570
|
-
(`in uvec4`/`in ivec4` with `vertexAttribIPointer`) — the float-only lowering above is
|
|
571
|
-
not a GLSL-ES-3.00 *language* limitation, it is a **runtime binding-layer**
|
|
572
|
-
limitation specific to this project's current ccpwgl consumer. A future
|
|
573
|
-
CarbonEngineJS-native consumer that binds attributes with `vertexAttribIPointer`
|
|
574
|
-
could use the stock HLSLcc `uvec4`/`ivec4` declarations directly and should not
|
|
575
|
-
inherit this workaround by default.
|
|
576
|
-
|
|
577
|
-
**Confidence: medium** — the *requirement* to avoid integer vertex-attribute types is
|
|
578
|
-
high confidence (proven by a specific regression + fix with before/after link
|
|
477
|
+
|
|
478
|
+
Declares a non-pixel stage input register: normally a vertex attribute whose
|
|
479
|
+
ISGN row supplies semantic name/index, component mask/type and, for non-VS
|
|
480
|
+
stages, interpolation. Stock lowering is at `toGLSLDeclaration.cpp:2061-2186`;
|
|
481
|
+
early-outs at `2070-2105` cover pseudo-inputs and already-array-declared
|
|
482
|
+
registers, not ordinary VS attributes.
|
|
483
|
+
|
|
484
|
+
| Declaration fact | Source and emitted form |
|
|
485
|
+
|---|---|
|
|
486
|
+
| Name | `GetDeclaredInputName`, `HLSLCrossCompilerContext.cpp:169-211`; VS prefix `in_` from `toGLSL.cpp:33`: `in_POSITION0`, `in_NORMAL0`, `in_TEXCOORD3`, `in_BLENDINDICES0`. |
|
|
487
|
+
| Storage | `InOutSupported` selects `in` for ES300 (`2121-2127`), not ES100 `attribute`/`varying`. |
|
|
488
|
+
| Precision | `highp` unless `OPERAND_MIN_PRECISION_*` says otherwise (`2129-2159`); such hints were rare in the studied corpus. |
|
|
489
|
+
| Type/width | `DeclareInput` (`232-390`, especially `265-291`): ISGN `eComponentType` selects `float`/`vecN`, `int`/`ivecN`, or `uint`/`uvecN`; `GetNumberBitsSet(ui32Mask)` sets width, **not the operand write mask**. |
|
|
490
|
+
| Text | `in <precision> <type> in_<SEMANTIC><index>;` (`362-388`, ordinary non-array branch). |
|
|
491
|
+
|
|
492
|
+
ISGN types are independent of the opening float-temp-register convention.
|
|
493
|
+
`HandleInputRedirect` (`1689-1806`) stages hull/domain phase inputs in
|
|
494
|
+
`phase{N}_Input...` temporaries; this VS/PS study needs no equivalent helper.
|
|
495
|
+
|
|
496
|
+
### Metadata-conditioned BINORMAL alias
|
|
497
|
+
|
|
498
|
+
DXBC names the split-tangent channel `BINORMAL`; Carbon/Trinity GR2 stream
|
|
499
|
+
metadata names the same channel `BITANGENT`
|
|
500
|
+
(`../shaderdiscovery/knowledge/trinity-metadata/shader-discovery-truths.md:126-133`,
|
|
501
|
+
`../shaderdiscovery/knowledge/carbon-metadata-contract/hlslcc-transpile-spike.md:195-201`).
|
|
502
|
+
This is a naming alias, not a different channel. The studied
|
|
503
|
+
`scripts/packageTr2WebglEffect.js` rewrites `in_BINORMAL{n}` to
|
|
504
|
+
`in_BITANGENT{n}` **after emission**, only when the VS contract declares a
|
|
505
|
+
`BITANGENT` pipeline input. Keep DXBC naming in opcode lowering; the
|
|
506
|
+
metadata-driven binder owns this compatibility requirement.
|
|
507
|
+
|
|
508
|
+
Recorded validation: regenerated `unpackedskinned_quadv5` and
|
|
509
|
+
`unpackedskinned_quadheatv5` had no `in_BINORMAL*` left and linked
|
|
510
|
+
336/336 and 80/80 WebGL2 programs.
|
|
511
|
+
|
|
512
|
+
### Historical CCPWGL integer-attribute constraint
|
|
513
|
+
|
|
514
|
+
The studied CCPWGL consumer used `vertexAttribPointer` for all mesh
|
|
515
|
+
channels, including blend indices, not `vertexAttribIPointer`.
|
|
516
|
+
`028-carbonwebgl-skinned-blend-index-abi-lowering.md` records that raw
|
|
517
|
+
integer attributes could link yet fail at runtime or produce invisible
|
|
518
|
+
geometry. Stock `DeclareInput` instead emits true `uvec4` for UINT32
|
|
519
|
+
`BLENDINDICES` (`270-274`). The historical proposal lowers integer-component
|
|
520
|
+
vertex declarations to float equivalents; its generalization remains unproven
|
|
521
|
+
per producer. The recorded workaround declares
|
|
522
|
+
`in vec4 in_BLENDINDICES0;` and casts at use sites; the general action plan
|
|
523
|
+
is in `TRANSPILING-GAPS.md`, “Ranked helper action plan”. Recorded
|
|
524
|
+
post-rewrite link counts are 336/336 and 240/240 programs, not proof of every
|
|
525
|
+
attribute producer's encoding.
|
|
526
|
+
|
|
527
|
+
The unresolved distinction is `floatBitsToUint(in_BLENDINDICES0)` for
|
|
528
|
+
bit-pattern-encoded uints versus `uint(in_BLENDINDICES0.x)` for plain
|
|
529
|
+
float index values. Verify each uploaded stream before generalizing.
|
|
530
|
+
GLSL ES300 supports genuine integer inputs with `vertexAttribIPointer`:
|
|
531
|
+
this is a CCPWGL binding constraint, **not a language limitation or a default
|
|
532
|
+
requirement for a CarbonEngineJS-native consumer**.
|
|
533
|
+
|
|
534
|
+
**Confidence: medium** — the *requirement* to avoid integer vertex-attribute types is
|
|
535
|
+
high confidence (proven by a specific regression + fix with before/after link
|
|
579
536
|
counts); the *exact* per-attribute cast convention (bitcast-reinterpret vs.
|
|
580
537
|
truncating-convert at the use site) is not nailed down to opcode-level precision in
|
|
581
538
|
the cited evidence and should be confirmed against the actual uploaded vertex-buffer
|
|
@@ -583,175 +540,116 @@ encoding for each integer semantic (`BLENDINDICES` specifically is documented;
|
|
|
583
540
|
generalize cautiously to any other integer-typed vertex semantic found in the corpus).
|
|
584
541
|
|
|
585
542
|
---
|
|
586
|
-
|
|
587
|
-
## `dcl_input_ps` (6995)
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
`
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
**
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
output, gated on `EXT_shader_framebuffer_fetch` + `HLSLCC_FLAG_SHADER_FRAMEBUFFER_FETCH`)
|
|
628
|
-
via `#define vs_SV_TargetN gl_LastFragData[N]` or a `layout(location=N) inout`
|
|
629
|
-
declaration. `GL_EXT_shader_framebuffer_fetch` **is not universally available in
|
|
630
|
-
WebGL2** and this project's target is standard WebGL2 fragment shaders reading only
|
|
631
|
-
their own current-fragment inputs — treat this branch as out of scope / not expected
|
|
632
|
-
to trigger in the EVE corpus; if it ever does, it is a target blocker requiring the
|
|
633
|
-
extension's presence to be verified at runtime, not silently assumed.
|
|
634
|
-
|
|
635
|
-
**WebGL2 notes**: `centroid`/`sample` interpolation qualifiers are core GLSL ES 3.00
|
|
636
|
-
keywords (no extension needed). `noperspective` is **not** — GLSL ES 3.00's spec does
|
|
637
|
-
not include `noperspective` as a keyword at all (it was added later, e.g. via
|
|
638
|
-
`NV_shader_noperspective_interpolation` for ES 3.0/3.1, and core only from ES 3.20);
|
|
639
|
-
WebGL2/ES 3.00 has no standard `noperspective` qualifier. The C++ source's own
|
|
640
|
-
`hasNoPerspective` gate (`eTargetLanguage <= LANG_ES_310 ? 0 : 1`, `2225`) is
|
|
641
|
-
therefore **correct as written, not stale or overly conservative** — it already
|
|
642
|
-
disables `noperspective` for `LANG_ES_300` (and `LANG_ES_310`) and only enables it for
|
|
643
|
-
targets above `LANG_ES_310`. This emitter should simply mirror that gate rather than
|
|
644
|
-
second-guess it: if any EVE pixel shader declares `INTERPOLATION_LINEAR_NOPERSPECTIVE`,
|
|
645
|
-
drop the qualifier for a `LANG_ES_300` target (falls back to perspective-correct
|
|
646
|
-
interpolation, a visible but non-fatal quality difference, vs. a hard compile error
|
|
647
|
-
from an unrecognized qualifier).
|
|
648
|
-
|
|
649
|
-
**Confidence: high** — the name-prefix pairing and integer-flat rule are high
|
|
650
|
-
confidence (direct source read, universal GLSL requirement); the
|
|
651
|
-
`noperspective`-in-ES-3.00 gate was re-checked directly against the GLSL ES 3.00
|
|
543
|
+
|
|
544
|
+
## `dcl_input_ps` (6995)
|
|
545
|
+
|
|
546
|
+
Declares a pixel input with an ISGN row and explicit
|
|
547
|
+
`value.eInterpolation` payload, unlike plain `dcl_input`.
|
|
548
|
+
`toGLSLDeclaration.cpp:2217-2423` emits
|
|
549
|
+
`<interp>in <precision> <type> vs_<SEMANTIC><index>;` through
|
|
550
|
+
`DeclareInput` (`2418`). Type/width and minimum-precision derivation
|
|
551
|
+
are as in `dcl_input` (precision: `2287-2317`). Storage is `in`
|
|
552
|
+
(`2228-2231`). `GetDeclaredInputName` takes the previous VS's
|
|
553
|
+
`vs_` prefix (`toGLSL.cpp:59-79`), matching its output prefix
|
|
554
|
+
(`toGLSL.cpp:34`).
|
|
555
|
+
|
|
556
|
+
Interpolation mapping (`2238-2284`):
|
|
557
|
+
|
|
558
|
+
| Input | Qualifier |
|
|
559
|
+
|---|---|
|
|
560
|
+
| UINT32/SINT32 | Always `flat`, regardless of DXBC mode (`2238-2242`). |
|
|
561
|
+
| `INTERPOLATION_CONSTANT` | `flat` |
|
|
562
|
+
| `LINEAR` | None |
|
|
563
|
+
| `LINEAR_CENTROID` | `centroid` |
|
|
564
|
+
| `LINEAR_NOPERSPECTIVE` | `noperspective` only with `hasNoPerspective` (`2263-2265`). |
|
|
565
|
+
| `LINEAR_SAMPLE` / `LINEAR_NOPERSPECTIVE_SAMPLE` | `sample` / `noperspective sample`, under the source gates. |
|
|
566
|
+
|
|
567
|
+
The study calls for mirroring `hasNoPerspective`
|
|
568
|
+
(`eTargetLanguage > LANG_ES_310`, `2225`), not removing the gate.
|
|
569
|
+
On ES300, dropping `noperspective` gives perspective-correct interpolation:
|
|
570
|
+
a visible quality difference, not an equivalent interpolation rule. No
|
|
571
|
+
custom helper is needed for the qualifiers.
|
|
572
|
+
|
|
573
|
+
**Framebuffer-fetch blocker:** `2319-2416` handles `SV_TargetN` as
|
|
574
|
+
both input and output using `#define vs_SV_TargetN gl_LastFragData[N]`
|
|
575
|
+
or `layout(location=N) inout`, gated by
|
|
576
|
+
`EXT_shader_framebuffer_fetch` plus
|
|
577
|
+
`HLSLCC_FLAG_SHADER_FRAMEBUFFER_FETCH`. This is outside the study's
|
|
578
|
+
standard WebGL2 target and was not expected in the EVE corpus. If encountered,
|
|
579
|
+
verify the extension at runtime; do not silently assume availability.
|
|
580
|
+
|
|
581
|
+
**Confidence: high** — the name-prefix pairing and integer-flat rule are high
|
|
582
|
+
confidence (direct source read, universal GLSL requirement); the
|
|
583
|
+
`noperspective`-in-ES-3.00 gate was re-checked directly against the GLSL ES 3.00
|
|
652
584
|
language facts (no `noperspective` keyword until ES 3.20 core / the
|
|
653
585
|
`NV_shader_noperspective_interpolation` extension) and confirmed correct as written,
|
|
654
586
|
so this is no longer an open question for this opcode.
|
|
655
587
|
|
|
656
588
|
---
|
|
657
|
-
|
|
658
|
-
## `dcl_output` (15197) — highest-frequency opcode in this family
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
(
|
|
666
|
-
|
|
667
|
-
`
|
|
668
|
-
instructions
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
-
|
|
675
|
-
`
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
`
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
without declaring anything (`619-620`) — that register is expected to be routed to
|
|
722
|
-
`gl_Position` via a separate `dcl_output_siv` `NAME_POSITION` declaration elsewhere
|
|
723
|
-
in the same instruction stream (see next section); do not double-declare it.
|
|
724
|
-
|
|
725
|
-
**Type rules**: identical component-type/count derivation to `dcl_input`/
|
|
726
|
-
`dcl_input_ps` (OSGN-driven, not write-mask-driven). The destination write mask on
|
|
727
|
-
the *declaration* itself only ever narrows which components get declared this pass
|
|
728
|
-
(merged across multiple partial declarations via `acOutputDeclared`); it has no
|
|
729
|
-
`_sat` concept — `saturate` only applies to the *instructions* that write the
|
|
730
|
-
register, never to a `dcl_output` declaration itself.
|
|
731
|
-
|
|
732
|
-
**Helpers needed**: `HandleOutputRedirect` — like `HandleInputRedirect`, this is
|
|
733
|
-
HLSLcc's hull-shader phase-output staging machinery; out of scope for this project's
|
|
734
|
-
vertex/pixel-only target.
|
|
735
|
-
|
|
736
|
-
**Edge cases — signature-only vertex outputs**: `023-signature-only-vertex-output-fallback.md`
|
|
737
|
-
documents `starmapnew`/`ubershader3d` variants whose OSGN declares outputs (`o3
|
|
738
|
-
-> COLOR2`, `o4 -> TEXCOORD1`, etc. for `starmapnew`; `o2 -> COLOR1`, `o7 ->
|
|
739
|
-
TEXCOORD4` for `ubershader3d`) with **no corresponding bytecode write** anywhere in
|
|
740
|
-
the instruction stream (audited: `references: 0`). GLSL ES 3.00 does not guarantee
|
|
741
|
-
zero-initialization of `out` varyings, and reading an unwritten varying downstream is
|
|
742
|
-
undefined/implementation-defined — this project's proven, adopted policy is to emit
|
|
743
|
-
an explicit deterministic zero-fill in early-main for any declared-but-never-written
|
|
744
|
-
output: `vs_COLOR2 = vec4(0.0);` before the translated instruction stream runs. Treat
|
|
745
|
-
this as expected, not a parser bug, for any output register with zero write
|
|
746
|
-
references.
|
|
747
|
-
|
|
748
|
-
**WebGL2 notes**: `layout(location=N)` for fragment-shader color outputs is
|
|
749
|
-
mandatory when more than one is declared (no implicit indexing); prefer
|
|
750
|
-
name-based linking (no `layout(location=...)`) for VS→PS varyings specifically,
|
|
751
|
-
per the recommendation above, to avoid cross-stage location-numbering mismatches.
|
|
752
|
-
|
|
753
|
-
**Confidence: high** for the SV_Target/varying declaration shape and naming
|
|
754
|
-
convention (heavily used, directly cited, corpus-validated linking counts exist
|
|
589
|
+
|
|
590
|
+
## `dcl_output` (15197) — highest-frequency opcode in this family
|
|
591
|
+
|
|
592
|
+
Declares an OSGN-bound output register. `toGLSLDeclaration.cpp:2760-2779`
|
|
593
|
+
calls `AddUserOutput` (`594-854`), gated by `OutputNeedsDeclaring`
|
|
594
|
+
(`HLSLCrossCompilerContext.cpp:279-330`). Its `acOutputDeclared`
|
|
595
|
+
bitmask deduplicates repeated partial-mask declarations; only undeclared
|
|
596
|
+
components trigger text. Type/width comes from OSGN
|
|
597
|
+
`eComponentType`/`GetNumberBitsSet(mask)` (`622-655`), not the
|
|
598
|
+
declaration write mask; precision comes from `OPERAND_MIN_PRECISION_*`
|
|
599
|
+
(`657-689`). Declarations have no `_sat`: saturation belongs to
|
|
600
|
+
instructions writing the register.
|
|
601
|
+
|
|
602
|
+
### Pixel outputs (691–795)
|
|
603
|
+
|
|
604
|
+
- `OPERAND_TYPE_OUTPUT_DEPTH`: builtin `gl_FragDepth` (`701-708`),
|
|
605
|
+
no declaration. The `EXT_frag_depth` shim (`703-706`) is ES100-only.
|
|
606
|
+
- `OUTPUT_DEPTH_GREATER_EQUAL` / `OUTPUT_DEPTH_LESS_EQUAL`:
|
|
607
|
+
`GL_ARB_conservative_depth` qualifiers (`709-723`). This study's
|
|
608
|
+
ES300 policy drops `depth_greater`/`depth_less` hints and writes
|
|
609
|
+
plain unconstrained `gl_FragDepth`; the desktop extension is not assumed.
|
|
610
|
+
The study treats this as removing a performance hint, not changing correctness.
|
|
611
|
+
- Ordinary `SV_TargetN` (`725-793`): empty output prefix plus semantic
|
|
612
|
+
and render-target index. First use of target N emits
|
|
613
|
+
`layout(location = N) out <precision><type> SV_TargetN;`
|
|
614
|
+
(`748-789`), including explicit locations for MRT instead of legacy
|
|
615
|
+
`gl_FragData[N]` (`WriteToFragData` is legacy/ES100-only).
|
|
616
|
+
|
|
617
|
+
**Location-gate correction:** `752-753` tests
|
|
618
|
+
`HaveInOutLocationQualifier || HaveLimitedInOutLocationQualifier`.
|
|
619
|
+
The former (`languages.h:102-109`, true for `>=LANG_410` or
|
|
620
|
+
`LANG_ES_310`) is false for ES300. The latter
|
|
621
|
+
(`languages.h:93-100`, “Only on vertex inputs and pixel outputs”) supplies
|
|
622
|
+
the true ES300 branch. Plain `dcl_input` tests the former alone and
|
|
623
|
+
therefore does not receive an explicit location there. Do not conflate the gates.
|
|
624
|
+
|
|
625
|
+
### Vertex outputs (796–846)
|
|
626
|
+
|
|
627
|
+
`vs_<SEMANTIC><index>` (`804`) matches the PS input name.
|
|
628
|
+
Integer outputs are `flat` (`810-814`); floats use cross-stage
|
|
629
|
+
`GetInterpolationMode` (`815-818`). This study recommends resolving
|
|
630
|
+
that mode from the paired PS `dcl_input_ps` because VS outputs encode no
|
|
631
|
+
interpolation payload. This remains a recommendation, qualified below.
|
|
632
|
+
|
|
633
|
+
`GetVaryingLocation` is at `821-825`; this study recommends omitting
|
|
634
|
+
explicit varying locations and linking by name to avoid VS/PS numbering
|
|
635
|
+
mismatches. If explicit varying locations are used, paired stage locations
|
|
636
|
+
must match. Final text (`838`):
|
|
637
|
+
`<interp>out <precision><type> vs_<SEMANTIC><index>;`.
|
|
638
|
+
VS register 0 with legacy `POS` returns early (`619-620`):
|
|
639
|
+
`dcl_output_siv NAME_POSITION` handles `gl_Position`, so do not
|
|
640
|
+
double-declare it. Hull-only `HandleOutputRedirect` is out of scope,
|
|
641
|
+
as is the hull control-point output case.
|
|
642
|
+
|
|
643
|
+
**Signature-only outputs:** `023-signature-only-vertex-output-fallback.md`
|
|
644
|
+
records OSGN outputs with zero bytecode write references:
|
|
645
|
+
`starmapnew` (`o3 -> COLOR2`, `o4 -> TEXCOORD1`) and
|
|
646
|
+
`ubershader3d` (`o2 -> COLOR1`, `o7 -> TEXCOORD4`). They are
|
|
647
|
+
expected inputs to the fallback, not parser defects. Since unwritten varyings
|
|
648
|
+
are not guaranteed zero, emit deterministic early-main initialization, e.g.
|
|
649
|
+
`vs_COLOR2 = vec4(0.0);`, before translated instructions.
|
|
650
|
+
|
|
651
|
+
**Confidence: high** for the SV_Target/varying declaration shape and naming
|
|
652
|
+
convention (heavily used, directly cited, corpus-validated linking counts exist
|
|
755
653
|
elsewhere in this family for related opcodes); **medium** for the
|
|
756
654
|
"resolve VS-output interpolation from the paired PS-input's `dcl_input_ps` mode"
|
|
757
655
|
policy recommendation, since that is this spec's own synthesis of how to handle
|
|
@@ -829,54 +727,34 @@ for every other branch, since none of them are exercised in this project's prove
|
|
|
829
727
|
VS/PS-only WebGL2 validation runs.
|
|
830
728
|
|
|
831
729
|
---
|
|
832
|
-
|
|
833
|
-
## `dcl_input_ps_siv` (538)
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
**
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
`
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
**Type rules**: `gl_FragCoord`/`hlslcc_FragCoord` is always `vec4`.
|
|
861
|
-
|
|
862
|
-
**Helpers needed**: the `hlslcc_FragCoord` early-main redirect line above — declare
|
|
863
|
-
it as a **named helper convention** (a fixed early-main statement emitted whenever a
|
|
864
|
-
`dcl_input_ps_siv NAME_POSITION` is seen), not a callable function, since it is a
|
|
865
|
-
local variable substitution rather than a reusable GLSL function.
|
|
866
|
-
|
|
867
|
-
**Edge cases**: `1.0/gl_FragCoord.w` divides by the fragment's window-space `w`
|
|
868
|
-
reciprocal — if `gl_FragCoord.w` is ever exactly `0.0` (a fragment at infinite
|
|
869
|
-
depth/degenerate clip-space w), this produces `inf`; no corpus evidence this occurs
|
|
870
|
-
in practice (fragments with `w=0` do not typically survive clipping), but note it as
|
|
871
|
-
a theoretical NaN/inf source worth being aware of, not one this project needs to
|
|
872
|
-
guard defensively against absent contrary evidence.
|
|
873
|
-
|
|
874
|
-
**WebGL2 notes**: `gl_FragCoord` is core; no extension needed. `gl_Layer` requires
|
|
875
|
-
geometry-shader support, out of scope for this project.
|
|
876
|
-
|
|
877
|
-
**Confidence: high** for `NAME_POSITION` (directly cited, dominant case — 538
|
|
878
|
-
occurrences is consistent with "most pixel shaders read `SV_Position`"); **low** for
|
|
879
|
-
`gl_Layer` (unreachable without geometry shaders in this project's stage set).
|
|
730
|
+
|
|
731
|
+
## `dcl_input_ps_siv` (538)
|
|
732
|
+
|
|
733
|
+
Pixel system-value inputs lower at `toGLSLDeclaration.cpp:2188-2207`:
|
|
734
|
+
|
|
735
|
+
- `NAME_POSITION` calls `AddBuiltinInput(psDecl, "gl_FragCoord")`
|
|
736
|
+
and emits this **early-main local substitution**, not a callable helper
|
|
737
|
+
(`2195`):
|
|
738
|
+
|
|
739
|
+
`vec4 hlslcc_FragCoord = vec4(gl_FragCoord.xyz, 1.0/gl_FragCoord.w);`
|
|
740
|
+
|
|
741
|
+
Redirect **every** PS `SV_Position` read to `hlslcc_FragCoord`,
|
|
742
|
+
not raw `gl_FragCoord`. Preserve xyz and the reciprocal-W expression
|
|
743
|
+
exactly; it reconciles HLSL/GLSL fourth-component conventions. Both are
|
|
744
|
+
`vec4`; the GLSL builtin needs no declaration or extension.
|
|
745
|
+
- `NAME_RENDER_TARGET_ARRAY_INDEX` maps to `gl_Layer`
|
|
746
|
+
(`2198-2201`), requiring upstream layered/geometry rendering outside
|
|
747
|
+
this study's scope.
|
|
748
|
+
- Other special names reach `ASSERT(0)` (`2203-2205`).
|
|
749
|
+
|
|
750
|
+
**Edge cases**: `1.0/gl_FragCoord.w` can produce infinity at exactly
|
|
751
|
+
zero W. No such corpus case was found; degenerate/infinite-depth fragments
|
|
752
|
+
normally do not survive clipping. Retain this as a theoretical NaN/Inf source,
|
|
753
|
+
not a request for a defensive guard without evidence.
|
|
754
|
+
|
|
755
|
+
**Confidence: high** for `NAME_POSITION` (directly cited, dominant case — 538
|
|
756
|
+
occurrences is consistent with "most pixel shaders read `SV_Position`"); **low** for
|
|
757
|
+
`gl_Layer` (unreachable without geometry shaders in this project's stage set).
|
|
880
758
|
|
|
881
759
|
---
|
|
882
760
|
|
|
@@ -1013,89 +891,55 @@ recording behavior above as written in the source, but do not assume it is
|
|
|
1013
891
|
exercised meaningfully by this project's corpus.
|
|
1014
892
|
|
|
1015
893
|
---
|
|
1016
|
-
|
|
1017
|
-
## `customdata` (159, encodes an Immediate Constant Buffer)
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
`
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
);
|
|
1066
|
-
```
|
|
1067
|
-
at global scope (every raw dword reinterpreted through `uintBitsToFloat`
|
|
1068
|
-
uniformly, whether or not it happens to be a "nice" float, sidestepping the
|
|
1069
|
-
`fpcheck`-conditional branching the CPU-target path uses) — simpler to implement
|
|
1070
|
-
correctly in a from-scratch JS emitter and avoids the early-main mutable-global
|
|
1071
|
-
pattern (which exists in stock HLSLcc mainly to support per-chunk dynamic-array
|
|
1072
|
-
splitting this project doesn't need, since `HaveDynamicIndexing` is true and a
|
|
1073
|
-
single flat `const vec4[]` can be indexed directly).
|
|
1074
|
-
|
|
1075
|
-
**Type rules**: every ICB element is exactly 4 raw dwords; **always reinterpret via
|
|
1076
|
-
`uintBitsToFloat`** rather than trusting a decimal float re-parse of the DXBC literal
|
|
1077
|
-
value, to guarantee exact bit-for-bit reproduction of the original constant
|
|
1078
|
-
(including denormals/NaNs/Infs the HLSL compiler folded in). Consumers needing an
|
|
1079
|
-
int/uint view of an ICB element bitcast again at the use site
|
|
1080
|
-
(`floatBitsToInt`/`floatBitsToUint`) exactly like any other float-register-file read.
|
|
1081
|
-
|
|
1082
|
-
**Helpers needed**: none — `uintBitsToFloat` is core GLSL ES 3.00.
|
|
1083
|
-
|
|
1084
|
-
**Edge cases**: NaN/Inf constants are the primary edge case, handled correctly by
|
|
1085
|
-
the bit-pattern-preserving encoding above — do not let a JS `JSON.stringify`/decimal
|
|
1086
|
-
round-trip of the float value silently normalize a NaN payload or lose an Inf's
|
|
1087
|
-
sign bit; carry the raw `uint32` dword through to the emitted GLSL untouched.
|
|
1088
|
-
Dynamic indexing of the ICB (`x0[aL]`-style reads) is a plain GLSL array-index
|
|
1089
|
-
expression on this project's target (`HaveDynamicIndexing` true for ES 300),
|
|
1090
|
-
needing none of stock HLSLcc's non-dynamic-indexing wrapper-function fallback.
|
|
1091
|
-
|
|
1092
|
-
**WebGL2 notes**: dynamic (non-constant-expression) array indexing of a global
|
|
1093
|
-
array is supported in GLSL ES 3.00's core profile (unlike GLSL ES 1.00, where it was
|
|
1094
|
-
restricted) — this project's target does not need the
|
|
1095
|
-
`DeclareDynamicIndexWrapper` fallback stock HLSLcc carries for older targets.
|
|
1096
|
-
|
|
1097
|
-
**Confidence: medium** — the NaN/Inf bit-pattern-preserving requirement and the
|
|
1098
|
-
"prefer the Switch-shaped `const vec4[]` over the non-Vulkan/non-Switch mutable
|
|
894
|
+
|
|
895
|
+
## `customdata` (159, encodes an Immediate Constant Buffer)
|
|
896
|
+
|
|
897
|
+
`customdata` subtype `ICB` embeds immediate constants in DXBC rather
|
|
898
|
+
than binding an external `cb#`. Each element is four raw dwords, with
|
|
899
|
+
fixed or dynamic indexing (`x0[aL]`-style reads).
|
|
900
|
+
|
|
901
|
+
### Stock target branches
|
|
902
|
+
|
|
903
|
+
Non-Vulkan/non-Switch (`toGLSLDeclaration.cpp:3007-3076`) walks
|
|
904
|
+
`m_ConstantArrayInfo.m_Chunks`: contiguous slices grouped by component width.
|
|
905
|
+
|
|
906
|
+
1. Declare mutable global arrays (`3017-3020`):
|
|
907
|
+
`float ImmCB_{phase}_{chunkFirst}_{rebase}[{size}];` for scalar chunks,
|
|
908
|
+
or `vec{N}` for N-wide chunks.
|
|
909
|
+
2. `DeclareDynamicIndexWrapper` (`3022-3029`) is for targets without
|
|
910
|
+
dynamic indexing. `HaveDynamicIndexing` is true for ES300: use real
|
|
911
|
+
arrays and direct index expressions, no wrapper.
|
|
912
|
+
3. Assign each element/component in early-main (`3032-3074`), not a
|
|
913
|
+
`const` initializer. Ordinary literals may be decimal, e.g.
|
|
914
|
+
`ImmCB_0_0_0[0] = 1.5;`. `fpcheck` (`3045-3048`,
|
|
915
|
+
`3067-3070`) preserves NaN/Inf as raw-bit expressions such as
|
|
916
|
+
`ImmCB_0_0_0[1] = uintBitsToFloat(uint(0x7FC00000u));`.
|
|
917
|
+
|
|
918
|
+
Vulkan (`2975-2990`, background only) instead declares
|
|
919
|
+
`const uvec4 ImmCB_{phase}[] = uvec4[{count}](uvec4(0x..., ...), ...);`.
|
|
920
|
+
Switch (`2991-3006`) uses a global `const vec4` array constructor
|
|
921
|
+
with `uintBitsToFloat`-preserved elements.
|
|
922
|
+
|
|
923
|
+
### Proposed ES300 shape — not a validated closure
|
|
924
|
+
|
|
925
|
+
This study recommends the Switch-like flat array, avoiding mutable early-main
|
|
926
|
+
assignments and chunk splitting when genuine dynamic indexing is available:
|
|
927
|
+
|
|
928
|
+
```glsl
|
|
929
|
+
const vec4 ImmCB_{phase}[{count}] = vec4[{count}](
|
|
930
|
+
vec4(uintBitsToFloat(0x3FC00000u), ...), ...);
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
Carry every raw `uint32` dword unchanged into `uintBitsToFloat`,
|
|
934
|
+
including denormals, NaN payloads and signed infinities; do not round-trip
|
|
935
|
+
through decimal floats or `JSON.stringify`. GLSL has no NaN/Inf literal
|
|
936
|
+
syntax. Integer consumers use `floatBitsToInt`/`floatBitsToUint`
|
|
937
|
+
as in the opening register convention. The bitcast is a core builtin, not a
|
|
938
|
+
custom helper. The proposed `const` initializer still requires the
|
|
939
|
+
actual WebGL2 compile/link validation stated below.
|
|
940
|
+
|
|
941
|
+
**Confidence: medium** — the NaN/Inf bit-pattern-preserving requirement and the
|
|
942
|
+
"prefer the Switch-shaped `const vec4[]` over the non-Vulkan/non-Switch mutable
|
|
1099
943
|
early-main array" recommendation are both this spec's own synthesis reasoned from
|
|
1100
944
|
reading three different target branches in the same source function, not a literal
|
|
1101
945
|
restatement of a single already-proven CarbonEngineJS-fork code path — validate the
|