IR type and related enums used by the Prism compiler. Defines IrPrecision and IrInterpolation enums and the IrType record struct which pairs a ShaderType with a precision hint and exposes convenience properties and common predefined instances.
using Editor.Prism.Core;
namespace Editor.Prism.Compiler.Ir;
/// <summary>Precision hint carried by an IR type. Ignored by backends that cannot express it.</summary>
public enum IrPrecision
{
/// <summary>Whatever the component type implies.</summary>
Default,
/// <summary>Minimum 16-bit precision (<c>min16float</c> and friends). Parses on SM 6.0.</summary>
Min16,
/// <summary>Force full precision.</summary>
Full
}
/// <summary>How a value is interpolated across a triangle when it travels through a varying.</summary>
public enum IrInterpolation
{
/// <summary>Perspective-correct linear interpolation. The default.</summary>
Linear,
/// <summary>Linear interpolation without perspective correction.</summary>
NoPerspective,
/// <summary>No interpolation; the provoking vertex's value is used.</summary>
NoInterpolation,
/// <summary>Interpolated at the pixel centroid.</summary>
Centroid,
/// <summary>Interpolated per sample.</summary>
Sample
}
/// <summary>
/// A fully-resolved IR type: a concrete <see cref="ShaderType"/> plus lowering hints. By the time
/// anything reaches the IR, every type variable has been solved away — an <see cref="IrType"/> that
/// is not <see cref="IsResolved"/> is a compiler bug, not a user error.
/// </summary>
public readonly record struct IrType( ShaderType Type, IrPrecision Precision )
{
/// <summary>Wrap a shader type with default precision.</summary>
public IrType( ShaderType type ) : this( type, IrPrecision.Default ) { }
/// <summary>void</summary>
public static readonly IrType Void = new( ShaderType.Void );
/// <summary>bool</summary>
public static readonly IrType Bool = new( ShaderType.Bool );
/// <summary>int</summary>
public static readonly IrType Int = new( ShaderType.Int );
/// <summary>uint</summary>
public static readonly IrType UInt = new( ShaderType.UInt );
/// <summary>float</summary>
public static readonly IrType Float = new( ShaderType.Float );
/// <summary>float2</summary>
public static readonly IrType Float2 = new( ShaderType.Float2 );
/// <summary>float3</summary>
public static readonly IrType Float3 = new( ShaderType.Float3 );
/// <summary>float4</summary>
public static readonly IrType Float4 = new( ShaderType.Float4 );
/// <summary>float4x4</summary>
public static readonly IrType Float4x4 = new( ShaderType.Float4x4 );
/// <summary>Wrap a shader type.</summary>
public static IrType Of( ShaderType type ) => new( type );
/// <summary>True when the underlying type is concrete.</summary>
public bool IsResolved => !Type.IsVoid;
/// <summary>Component count of the underlying type.</summary>
public int Components => Type.Components;
/// <summary>HLSL spelling, including the precision prefix when one applies.</summary>
public string Hlsl => Precision == IrPrecision.Min16 && Type.IsNumeric && Type.IsFloatingPoint
? "min16" + Type.Hlsl
: Type.Hlsl;
/// <summary>Slang spelling.</summary>
public string Slang => Type.Slang;
/// <summary>Implicitly widen a shader type into an IR type.</summary>
public static implicit operator IrType( ShaderType type ) => new( type );
/// <summary>Implicitly narrow an IR type back to its shader type.</summary>
public static implicit operator ShaderType( IrType type ) => type.Type;
/// <inheritdoc/>
public override string ToString() => Hlsl;
}