Class FxParseResult
- Namespace
- ShadowDusk.HLSL.Ast
- Assembly
- ShadowDusk.HLSL.dll
The output of the FX9 pre-parser: stripped HLSL plus all extracted FX9 metadata.
public sealed record FxParseResult : IEquatable<FxParseResult>
- Inheritance
-
FxParseResult
- Implements
- Inherited Members
Properties
ExplicitGlSamplerSlots
TEXTURE name -> the OpenGL texture unit an explicit register(sN) on its LEGACY
sampler declaration pins it to. Keyed on the texture (synthesized X_SDTexture, or
the one a sampler_state block references) because that is what the GL sampler
table joins on. Empty when nothing declared a register.
This exists because the register clause is otherwise destroyed before DXC sees
it: the SM4 rewrite turns sampler X : register(s2); into
Texture2D X_SDTexture; SamplerState X;, so neither reflection nor the SPIR-V can
recover the 2. The clause is recorded here rather than preserved in the rewritten HLSL
deliberately: emitting it would change what DXC compiles and move the DirectX, DX12,
Vulkan and FNA bytes, none of which have a reported defect. Recording it changes the
OpenGL slot allocation only.
Legacy form only, and that is measured, not an oversight (2026-08-02).
mgfxc honours the annotation exactly here, because compiled at ps_3_0 a
legacy sampler IS the combined sampler and register(sN) pins its SM3
sampler register. For the modern spelling it does not: given
Texture2D T : register(t3); SamplerState S : register(s2); the mgfxc
OpenGL build puts the pair on slot 0 regardless, allocating by texture declaration
order. Recording modern registers here would therefore make us DIVERGE.
public IReadOnlyDictionary<string, int> ExplicitGlSamplerSlots { get; init; }
Property Value
ParameterAnnotations
Annotation blocks attached to global parameter declarations.
public required IReadOnlyList<ParameterAnnotation> ParameterAnnotations { get; init; }
Property Value
ReservedGlSamplerSlots
OpenGL sampler registers that an explicit register(sN) on a MODERN
SamplerState declaration takes out of circulation, so a synthesized combined
sampler must be allocated around them rather than onto them.
Compiling for OpenGL means compiling at ps_3_0, where a texture and a sampler
are ONE object sharing a single register namespace. A modern SamplerState still sits
at its declared register, but the combined sampler fxc synthesizes for each
(texture, sampler) pair cannot reuse it. Measured: with one texture and
SamplerState S : register(s0), mgfxc emits ps_s1, not
ps_s0.
This is what makes the LEGACY case stop looking like a special case. There the
sampler is the combined object, so it both reserves its register and occupies it,
landing the pair exactly on N. Same allocator, different starting facts.
public IReadOnlySet<int> ReservedGlSamplerSlots { get; init; }
Property Value
Samplers
All sampler declarations with sampler_state blocks extracted from the source.
public required IReadOnlyList<SamplerInfo> Samplers { get; init; }
Property Value
StrippedHlsl
HLSL source with all FX9 blocks stripped, preserving line numbers for error reporting.
public required string StrippedHlsl { get; init; }
Property Value
Techniques
All technique blocks extracted from the source.
public required IReadOnlyList<TechniqueInfo> Techniques { get; init; }