Donner SVG 0.8.0-pre
SVG editor and embeddable C⁠+⁠+⁠20 engine.
Loading...
Searching...
No Matches
IrExpr.h File Reference

Typed, immutable expression nodes for the donner::gpu::shader IR. More...

#include <cstdint>
#include <memory>
#include <ostream>
#include <span>
#include <string>
#include <string_view>
#include <variant>
#include <vector>
#include "donner/base/RcString.h"
#include "donner/gpu/shader/IrType.h"
#include "donner/gpu/shader/ShaderResult.h"
Include dependency graph for IrExpr.h:
This graph shows which files directly or indirectly include this file:

Classes

class  donner::gpu::shader::IrExpr
 A typed, immutable IR expression handle. More...
struct  donner::gpu::shader::IrExpr::RefInfo
 One name reference found inside an expression tree (see collectRefs). More...
struct  donner::gpu::shader::IrExpr::Node
 Internal storage for IrExpr nodes; public for the factory, serialization, and emitter implementations only. More...

Namespaces

namespace  donner
 Top-level Donner namespace, which is split into different sub-namespaces such as donner::svg and donner::css.

Enumerations

enum class  donner::gpu::shader::BinaryOp : uint8_t {
  Add ,
  Sub ,
  Mul ,
  Div ,
  Mod ,
  Lt ,
  Le ,
  Gt ,
  Ge ,
  Eq ,
  Ne ,
  And ,
  Or ,
  Shr
}
 Binary operators. More...
enum class  donner::gpu::shader::BuiltinFn : uint8_t {
  Abs ,
  Min ,
  Max ,
  Clamp ,
  Saturate ,
  Fract ,
  Sqrt ,
  Length ,
  Dot ,
  Normalize ,
  Fwidth ,
  Round ,
  Select ,
  Any ,
  All ,
  TextureSample ,
  TextureLoad ,
  TextureDimensions
}
 Builtin functions callable from IR (the solid-fill subset; everything else is rejected). More...
enum class  donner::gpu::shader::RefKind : uint8_t {
  Param ,
  Let ,
  Var ,
  Constant ,
  Resource
}
 What a name reference refers to; determines mutability and serialization. More...

Functions

std::ostream & donner::gpu::shader::operator<< (std::ostream &os, BinaryOp value)
 Ostream output operator, e.g. add.
std::string_view donner::gpu::shader::BuiltinFnName (BuiltinFn fn)
 The builtin's spelling.
std::ostream & donner::gpu::shader::operator<< (std::ostream &os, BuiltinFn value)
 Ostream output operator, e.g. clamp.
std::ostream & donner::gpu::shader::operator<< (std::ostream &os, RefKind value)
 Ostream output operator, e.g. var.
IrExpr donner::gpu::shader::LiteralF32 (float value)
 f32 literal.
IrExpr donner::gpu::shader::LiteralI32 (int32_t value)
 i32 literal.
IrExpr donner::gpu::shader::LiteralU32 (uint32_t value)
 u32 literal.
IrExpr donner::gpu::shader::LiteralBool (bool value)
 bool literal.
IrExpr donner::gpu::shader::MakeRef (RefKind kind, const RcString &name, const IrType &type)
 Named reference; normally produced by the function/module builders, which guarantee the name exists with the given type.
ShaderResult< IrExprdonner::gpu::shader::Add (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="add")
 lhs + rhs for matching numeric scalar/vector types.
ShaderResult< IrExprdonner::gpu::shader::Sub (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="sub")
 lhs - rhs for matching numeric scalar/vector types.
ShaderResult< IrExprdonner::gpu::shader::Mul (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="mul")
 lhs * rhs: matching numeric scalar/vector types, vector*scalar, scalar*vector, mat4x4f*vec4f, or mat4x4f*mat4x4f (required by the solid-fill vertex stage, which composes the per-instance matrix with the MVP).
ShaderResult< IrExprdonner::gpu::shader::Mod (const IrExpr &lhs, const IrExpr &rhs, const RcString &label=RcString())
 lhs / rhs for matching numeric scalar/vector types.
ShaderResult< IrExprdonner::gpu::shader::Div (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="div")
ShaderResult< IrExprdonner::gpu::shader::Lt (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="lt")
 Every comparison below takes two operands of the same type, and both may be scalars or vectors: a scalar comparison yields bool, a vector comparison compares componentwise and yields a bool vector of the same size, which is how WGSL, MSL, and SPIR-V all define it. Any and All reduce such a vector back to a single bool.
ShaderResult< IrExprdonner::gpu::shader::Le (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="le")
 lhs <= rhs componentwise; yields bool or a bool vector.
ShaderResult< IrExprdonner::gpu::shader::Gt (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="gt")
 lhs > rhs componentwise; yields bool or a bool vector.
ShaderResult< IrExprdonner::gpu::shader::Ge (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="ge")
 lhs >= rhs componentwise; yields bool or a bool vector.
ShaderResult< IrExprdonner::gpu::shader::Eq (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="eq")
 lhs == rhs componentwise for matching scalars or vectors; yields bool or a bool vector.
ShaderResult< IrExprdonner::gpu::shader::Ne (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="ne")
 lhs != rhs componentwise for matching scalars or vectors; yields bool or a bool vector.
ShaderResult< IrExprdonner::gpu::shader::Shr (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="shr")
 lhs >> rhs, a logical shift right on matching-size u32 scalars or vectors.
ShaderResult< IrExprdonner::gpu::shader::And (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="and")
 lhs && rhs for bools.
ShaderResult< IrExprdonner::gpu::shader::Or (const IrExpr &lhs, const IrExpr &rhs, const RcString &label="or")
 lhs || rhs for bools.
ShaderResult< IrExprdonner::gpu::shader::Not (const IrExpr &operand, const RcString &label="not")
 !operand for bool.
ShaderResult< IrExprdonner::gpu::shader::Neg (const IrExpr &operand, const RcString &label="neg")
 -operand for f32/i32 scalars and vectors (u32 has no unary minus).
ShaderResult< IrExprdonner::gpu::shader::Member (const IrExpr &base, const RcString &memberName, const RcString &label="member")
 Struct member access base.member.
ShaderResult< IrExprdonner::gpu::shader::Swizzle (const IrExpr &base, std::string_view components, const RcString &label="swizzle")
 Vector swizzle base.xy (components from xyzw, 1-4 of them, within the vector size).
ShaderResult< IrExprdonner::gpu::shader::Index (const IrExpr &base, const IrExpr &index, const RcString &label="index")
 Indexing base[index] for sized arrays, runtime arrays, and vectors, with an i32/u32 index.
ShaderResult< IrExprdonner::gpu::shader::ConstructVector (const IrType &target, std::vector< IrExpr > args, const RcString &label="construct")
 Vector constructor: vecN<T>(...) from scalars and smaller vectors of element type T totaling exactly N components, or a single scalar splat.
ShaderResult< IrExprdonner::gpu::shader::ConstructMat2x2f (std::vector< IrExpr > columns, const RcString &label=RcString())
 mat2x2<f32> constructor from two vec2<f32> columns.
ShaderResult< IrExprdonner::gpu::shader::ConstructMat4x4f (std::vector< IrExpr > columns, const RcString &label="mat4x4f")
 Matrix constructor: mat4x4f(c0, c1, c2, c3) from four vec4f columns.
ShaderResult< IrExprdonner::gpu::shader::Convert (const IrType &target, const IrExpr &value, const RcString &label="convert")
 Scalar or vector element-type conversion, e.g.
ShaderResult< IrExprdonner::gpu::shader::CallBuiltin (BuiltinFn fn, std::vector< IrExpr > args, const RcString &label="call")
 Builtin function call by enum.
ShaderResult< IrExprdonner::gpu::shader::CallBuiltinNamed (std::string_view name, std::vector< IrExpr > args, const RcString &label="call")
 Builtin function call by name; unknown names fail closed (only the solid-fill builtin subset exists).
IrExpr donner::gpu::shader::MakeCallUser (const RcString &name, const IrType &returnType, std::vector< IrExpr > args)
 User-defined function call; normally produced by the function builder, which checks the signature against the module's registered functions.

Detailed Description

Typed, immutable expression nodes for the donner::gpu::shader IR.

Every expression is type-checked at construction: the factory functions return ShaderResult and fail closed on ill-typed operands, unknown swizzles, bad constructor arity, indexing of non-indexable types, and unknown builtin functions. Expression values are cheap immutable handles; sharing a subexpression is sharing, not mutation.


Class Documentation

◆ donner::gpu::shader::IrExpr::RefInfo

struct donner::gpu::shader::IrExpr::RefInfo

One name reference found inside an expression tree (see collectRefs).

Class Members
RefKind kind What the name refers to.
RcString name Referenced name.
IrType type Type the reference was created with.

◆ donner::gpu::shader::IrExpr::Node

struct donner::gpu::shader::IrExpr::Node

Internal storage for IrExpr nodes; public for the factory, serialization, and emitter implementations only.

Class Members
BinaryOp binaryOp = BinaryOp::Add Binary payload.
BuiltinFn builtin = BuiltinFn::Abs Builtin payload.
vector< IrExpr > children Operands, in order.
Kind kind = Kind::Literal Node kind.
variant< bool, int32_t, uint32_t, float > literal = 0.0f Literal payload.
bool mutableLvalue = false Assignable access chain.
RcString name Ref/member/callee name.
RefKind refKind = RefKind::Let Ref payload.
string swizzle Swizzle components.
IrType type = IrType::F32() Result type.
UnaryOp unaryOp = UnaryOp::Neg Unary payload.

Enumeration Type Documentation

◆ BinaryOp

enum class donner::gpu::shader::BinaryOp : uint8_t
strong

Binary operators.

Enumerator
Add 

+

Sub 

-

Mul 

* (scalars, vectors, vector*scalar, mat2x2f*vec2f, mat4x4f*vec4f, mat4x4f*mat4x4f)

Div 

/

Mod 

% (integer scalars only)

Lt 

<

Le 

<=

Gt 

>

Ge 

>=

Eq 

==

Ne 

!=

And 

&&

Or 

||

Shr 

>> (logical shift right; unsigned integers only)

◆ BuiltinFn

enum class donner::gpu::shader::BuiltinFn : uint8_t
strong

Builtin functions callable from IR (the solid-fill subset; everything else is rejected).

Enumerator
Abs 

abs(x)

Min 

min(a, b)

Max 

max(a, b)

Clamp 

clamp(x, lo, hi)

Saturate 

saturate(x)

Fract 

fract(x)

Sqrt 

sqrt(x)

Length 

length(v)

Dot 

dot(a, b)

Normalize 

normalize(v)

Fwidth 

fwidth(x) (fragment stage)

Round 

round(x)

Select 

select(falseVal, trueVal, cond)

Any 

any(v) - true if any component of a bool vector is true.

All 

all(v) - true if every component of a bool vector is true.

TextureSample 

textureSample(texture, sampler, coords)

TextureLoad 

textureLoad(texture, coords, level)

TextureDimensions 

textureDimensions(texture)

◆ RefKind

enum class donner::gpu::shader::RefKind : uint8_t
strong

What a name reference refers to; determines mutability and serialization.

Enumerator
Param 

Function parameter (immutable).

Let 

Function-scope immutable binding.

Var 

Function-scope mutable variable (assignable).

Constant 

Module-scope constant.

Resource 

Module-scope resource binding.

Function Documentation

◆ Add()

ShaderResult< IrExpr > donner::gpu::shader::Add ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "add" )

lhs + rhs for matching numeric scalar/vector types.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ And()

ShaderResult< IrExpr > donner::gpu::shader::And ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "and" )

lhs && rhs for bools.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ BuiltinFnName()

std::string_view donner::gpu::shader::BuiltinFnName ( BuiltinFn fn)

The builtin's spelling.

WGSL, MSL, and the IR's own serialization all use it, because every builtin in scope is named identically in both target languages.

Parameters
fnBuiltin to name.

◆ CallBuiltin()

ShaderResult< IrExpr > donner::gpu::shader::CallBuiltin ( BuiltinFn fn,
std::vector< IrExpr > args,
const RcString & label = "call" )

Builtin function call by enum.

Parameters
fnBuiltin to call.
argsCall arguments.
labelDiagnostic label.

◆ CallBuiltinNamed()

ShaderResult< IrExpr > donner::gpu::shader::CallBuiltinNamed ( std::string_view name,
std::vector< IrExpr > args,
const RcString & label = "call" )

Builtin function call by name; unknown names fail closed (only the solid-fill builtin subset exists).

Parameters
nameBuiltin name, e.g. "clamp".
argsCall arguments.
labelDiagnostic label.

◆ ConstructMat2x2f()

ShaderResult< IrExpr > donner::gpu::shader::ConstructMat2x2f ( std::vector< IrExpr > columns,
const RcString & label = RcString() )

mat2x2<f32> constructor from two vec2<f32> columns.

Parameters
columnsExactly two vec2<f32> columns, in column-major order.
labelDiagnostic label.

◆ ConstructMat4x4f()

ShaderResult< IrExpr > donner::gpu::shader::ConstructMat4x4f ( std::vector< IrExpr > columns,
const RcString & label = "mat4x4f" )

Matrix constructor: mat4x4f(c0, c1, c2, c3) from four vec4f columns.

Parameters
columnsThe four column vectors.
labelDiagnostic label.

◆ ConstructVector()

ShaderResult< IrExpr > donner::gpu::shader::ConstructVector ( const IrType & target,
std::vector< IrExpr > args,
const RcString & label = "construct" )

Vector constructor: vecN<T>(...) from scalars and smaller vectors of element type T totaling exactly N components, or a single scalar splat.

Parameters
targetVector type to construct.
argsConstructor arguments.
labelDiagnostic label.

◆ Convert()

ShaderResult< IrExpr > donner::gpu::shader::Convert ( const IrType & target,
const IrExpr & value,
const RcString & label = "convert" )

Scalar or vector element-type conversion, e.g.

f32(x), u32(x), vec2i(vec2f). The target must be a numeric scalar or vector; vector conversions require matching component counts, and a numeric scalar argument may also convert to a vector by splat (e.g. vec2i(0)).

Parameters
targetConversion target type.
valueValue to convert.
labelDiagnostic label.

◆ Eq()

ShaderResult< IrExpr > donner::gpu::shader::Eq ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "eq" )

lhs == rhs componentwise for matching scalars or vectors; yields bool or a bool vector.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ Ge()

ShaderResult< IrExpr > donner::gpu::shader::Ge ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "ge" )

lhs >= rhs componentwise; yields bool or a bool vector.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ Gt()

ShaderResult< IrExpr > donner::gpu::shader::Gt ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "gt" )

lhs > rhs componentwise; yields bool or a bool vector.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ Index()

ShaderResult< IrExpr > donner::gpu::shader::Index ( const IrExpr & base,
const IrExpr & index,
const RcString & label = "index" )

Indexing base[index] for sized arrays, runtime arrays, and vectors, with an i32/u32 index.

Parameters
baseIndexable expression.
indexIndex expression.
labelDiagnostic label.

◆ Le()

ShaderResult< IrExpr > donner::gpu::shader::Le ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "le" )

lhs <= rhs componentwise; yields bool or a bool vector.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ LiteralBool()

IrExpr donner::gpu::shader::LiteralBool ( bool value)

bool literal.

Parameters
valueLiteral value.

◆ LiteralF32()

IrExpr donner::gpu::shader::LiteralF32 ( float value)

f32 literal.

Parameters
valueLiteral value.

◆ LiteralI32()

IrExpr donner::gpu::shader::LiteralI32 ( int32_t value)

i32 literal.

Parameters
valueLiteral value.

◆ LiteralU32()

IrExpr donner::gpu::shader::LiteralU32 ( uint32_t value)

u32 literal.

Parameters
valueLiteral value.

◆ Lt()

ShaderResult< IrExpr > donner::gpu::shader::Lt ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "lt" )

Every comparison below takes two operands of the same type, and both may be scalars or vectors: a scalar comparison yields bool, a vector comparison compares componentwise and yields a bool vector of the same size, which is how WGSL, MSL, and SPIR-V all define it. Any and All reduce such a vector back to a single bool.

The ordered comparisons (Lt, Le, Gt, Ge) additionally require numeric operands, since bool has no ordering. Eq and Ne do not: comparing two bools, or two bool vectors, is meaningful and allowed. lhs < rhs componentwise; yields bool or a bool vector.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ MakeCallUser()

IrExpr donner::gpu::shader::MakeCallUser ( const RcString & name,
const IrType & returnType,
std::vector< IrExpr > args )

User-defined function call; normally produced by the function builder, which checks the signature against the module's registered functions.

Parameters
nameCallee name.
returnTypeCallee return type.
argsCall arguments (already checked against the signature).

◆ MakeRef()

IrExpr donner::gpu::shader::MakeRef ( RefKind kind,
const RcString & name,
const IrType & type )

Named reference; normally produced by the function/module builders, which guarantee the name exists with the given type.

Parameters
kindWhat the name refers to.
nameReferenced name.
typeType of the referenced value.

◆ Member()

ShaderResult< IrExpr > donner::gpu::shader::Member ( const IrExpr & base,
const RcString & memberName,
const RcString & label = "member" )

Struct member access base.member.

Parameters
baseStruct-typed expression.
memberNameMember to access.
labelDiagnostic label.

◆ Mod()

ShaderResult< IrExpr > donner::gpu::shader::Mod ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = RcString() )

lhs / rhs for matching numeric scalar/vector types.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label. Integer remainder lhs % rhs.
lhsLeft operand (i32 or u32 scalar).
rhsRight operand (same type as lhs).
labelDiagnostic label.

◆ Mul()

ShaderResult< IrExpr > donner::gpu::shader::Mul ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "mul" )

lhs * rhs: matching numeric scalar/vector types, vector*scalar, scalar*vector, mat4x4f*vec4f, or mat4x4f*mat4x4f (required by the solid-fill vertex stage, which composes the per-instance matrix with the MVP).

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ Ne()

ShaderResult< IrExpr > donner::gpu::shader::Ne ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "ne" )

lhs != rhs componentwise for matching scalars or vectors; yields bool or a bool vector.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ Neg()

ShaderResult< IrExpr > donner::gpu::shader::Neg ( const IrExpr & operand,
const RcString & label = "neg" )

-operand for f32/i32 scalars and vectors (u32 has no unary minus).

Parameters
operandOperand.
labelDiagnostic label.

◆ Not()

ShaderResult< IrExpr > donner::gpu::shader::Not ( const IrExpr & operand,
const RcString & label = "not" )

!operand for bool.

Parameters
operandOperand.
labelDiagnostic label.

◆ operator<<() [1/3]

std::ostream & donner::gpu::shader::operator<< ( std::ostream & os,
BinaryOp value )

Ostream output operator, e.g. add.

Parameters
osOutput stream.
valueValue to output.

◆ operator<<() [2/3]

std::ostream & donner::gpu::shader::operator<< ( std::ostream & os,
BuiltinFn value )

Ostream output operator, e.g. clamp.

Parameters
osOutput stream.
valueValue to output.

◆ operator<<() [3/3]

std::ostream & donner::gpu::shader::operator<< ( std::ostream & os,
RefKind value )

Ostream output operator, e.g. var.

Parameters
osOutput stream.
valueValue to output.

◆ Or()

ShaderResult< IrExpr > donner::gpu::shader::Or ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "or" )

lhs || rhs for bools.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ Shr()

ShaderResult< IrExpr > donner::gpu::shader::Shr ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "shr" )

lhs >> rhs, a logical shift right on matching-size u32 scalars or vectors.

Unsigned only: an arithmetic shift of a signed value is a different instruction on every backend, and nothing in the shader set shifts a signed value. There is no left-shift sibling for the same reason - no shader uses one, and an operator with no caller has no golden that would catch it being emitted wrong.

Parameters
lhsValue to shift.
rhsShift amount, u32 of the same shape as lhs.
labelDiagnostic label.

◆ Sub()

ShaderResult< IrExpr > donner::gpu::shader::Sub ( const IrExpr & lhs,
const IrExpr & rhs,
const RcString & label = "sub" )

lhs - rhs for matching numeric scalar/vector types.

Parameters
lhsLeft operand.
rhsRight operand.
labelDiagnostic label.

◆ Swizzle()

ShaderResult< IrExpr > donner::gpu::shader::Swizzle ( const IrExpr & base,
std::string_view components,
const RcString & label = "swizzle" )

Vector swizzle base.xy (components from xyzw, 1-4 of them, within the vector size).

Parameters
baseVector-typed expression.
componentsSwizzle string, e.g. "xy".
labelDiagnostic label.