Crate naga[−][src]
Expand description
Universal shader translator.
The central structure of the crate is Module
. A Module
contains:
-
EntryPoint
s, the main functions for pipeline stages like vertex shading or fragment shading, -
Function
s, representing functions used byEntryPoint
s and otherFunction
s, -
Constant
s andGlobalVariable
s used byEntryPoint
s andFunction
s, and -
Type
s used by the above.
The body of an EntryPoint
or Function
is represented using two types:
-
An
Expression
produces a value, but has no side effects or control flow.Expressions
include variable references, unary and binary operators, and so on. -
A
Statement
can have side effects and structured control flow.Statement
s do not produce a value, other than by storing one in some designated place.Statements
include blocks, conditionals, and loops, but also operations that have side effects, like stores and function calls.
Statement
s form a tree, with pointers into the DAG of Expression
s.
Restricting side effects to statements simplifies analysis and code generation.
A Naga backend can generate code to evaluate an Expression
however and
whenever it pleases, as long as it is certain to observe the side effects of all
previously executed Statement
s.
Many Statement
variants use the Block
type, which is simply Vec<Block>
,
representing a series of statements executed in order. The body of an
EntryPoint
s or Function
is a Block
, and Statement
has a
Block
variant.
To improve translator performance and reduce memory usage, most structures are
stored in an Arena
. An Arena<T>
stores a series of T
values, indexed by
Handle<T>
values, which are just wrappers around integer indexes.
For example, a Function
’s expressions are stored in an Arena<Expression>
,
and compound expressions refer to their sub-expressions via Handle<Expression>
values. (When examining the serialized form of a Module
, note that the first
element of an Arena
has an index of 1, not 0.)
Function Calls
The Naga IR’s representation of function calls is unusual. Most languages treat
function calls as expressions, but because calls may have side effects, Naga
represents them with Statement::Call
. A call statement may designate a
particular Expression
to represent its return value, if any, which can be used
by subsequent statements and their expressions.
Expression
evaluation time and scope
While the order of execution of Statement
s is apparent from their structure,
it is not so obvious exactly when a given Expression
should be evaluated,
since many Statement
s and Expression
s may refer to its value. But it is
essential to clearly specify an expression’s evaluation time, since that
determines which statements’ effects the expression should observe. It is also
helpful to backends to limit the visibility of an Expression
’s value to a
portion of the statement tree.
An Expression
may only be used, whether by a Statement
or another
Expression
, if one of the following is true:
-
The expression is an
Expression::Constant
,Expression::FunctionArgument
, orExpression::GlobalVariable
. -
The expression is an
Expression::LocalVariable
that is either thepointer
(destination) of aStatement::Store
, or initialized by some previously executedStatement::Store
. -
The expression is the
result
of aStatement::Call
, representing the call’s return value. The call must be ‘in scope’ for the use (see below). -
The expression is included in the range of some
Statement::Emit
that is ‘in scope’ for the use (see below). TheExpression::needs_pre_emit
method returnstrue
if the given expression does not need to be covered by anEmit
statement.
The scope of an expression evaluated by an Emit
statement covers the
subsequent expressions in that Emit
, any following statements in the Block
to which that Emit
belongs (if any) and their sub-statements (if any).
If a Call
statement has a result
expression, then it is in scope for any
statements following the Call
in the Block
to which that Call
belongs (if
any) and their sub-statements (if any).
This means that, for example, an expression evaluated by some statement in a
nested Block
is not available in the Block
’s parents. Such a value would
need to be stored in a local variable to be carried upwards in the statement
tree.
Variables
An Expression::LocalVariable
or Expression::GlobalVariable
produces a
pointer value referring to the variable’s value. To retrieve the variable’s
value, use an Expression::Load
, with the variable expression as its
pointer
operand. To assign to a variable, use a Statement::Store
with the
variable expression as its pointer
operand.
As an exception, Expression::GlobalVariable
s referring to
GlobalVariable
s whose class
is StorageClass::Handle
produce the
variable’s value directly; no Load
is needed. These global variables refer to
opaque values like samplers and images.
Modules
back | Functions which export shader modules into binary and text formats. |
front | Parsers which load shaders into memory. |
proc | Module processing functionality. |
valid |
Structs
Arena | An arena holding some kind of component (e.g., type, constant, instruction, etc.) that can be referenced. |
Barrier | Memory barrier flags. |
Constant | Constant value. |
EarlyDepthTest | Early fragment tests. In a standard situation if a driver determines that it is possible to switch on early depth test it will. Typical situations when early depth test is switched off: |
EntryPoint | Exported function, to be run at a certain stage in the pipeline. |
Function | A function defined in the module. |
FunctionArgument | A function argument. |
FunctionResult | |
GlobalVariable | Variable defined at module level. |
Handle | A strongly typed reference to an arena item. |
LocalVariable | Variable defined at function level. |
Module | Shader module. |
Range | A strongly typed range of handles. |
ResourceBinding | Pipeline binding information for global resources. |
StorageAccess | Flags describing an image. |
StructMember | Member of a user-defined structure. |
SwitchCase | A case for a switch statement. |
Type | A data type declared in the module. |
Enums
ArraySize | Size of an array. |
BinaryOperator | Operation that can be applied on two values. |
Binding | Describes how an input/output variable is to be bound. |
BuiltIn | Built-in inputs and outputs. |
ConservativeDepth | Enables adjusting depth without disabling early Z. |
ConstantInner | Additional information, dependent on the kind of constant. |
DerivativeAxis | Axis on which to compute a derivative. |
Expression | An expression that can be evaluated to obtain a value. |
ImageClass | Sub-class of the image type. |
ImageDimension | The number of dimensions an image has. |
ImageQuery | Type of an image query. |
Interpolation | The interpolation qualifier of a binding or struct field. |
MathFunction | Built-in shader function for math. |
RelationalFunction | Built-in shader function for testing relation between values. |
SampleLevel | Sampling modifier to control the level of detail. |
Sampling | The sampling qualifiers of a binding or struct field. |
ScalarKind | Primitive type for a scalar. |
ScalarValue | A literal scalar value, used in constants. |
ShaderStage | Stage of the programmable pipeline. |
Statement | Instructions which make up an executable block. |
StorageClass | Class of storage for variables. |
StorageFormat | |
SwizzleComponent | Component selection for a vector swizzle. |
TypeInner | Enum with additional information, depending on the kind of type. |
UnaryOperator | Operation that can be applied on a single value. |
VectorSize | Number of components in a vector. |
Constants
BOOL_WIDTH | Width of a boolean type, in bytes. |
Type Definitions
Block | A code block is just a vector of statements. |
Bytes | Number of bytes per scalar. |
FastHashMap | Hash map that is faster but not resilient to DoS attacks. |
FastHashSet | Hash set that is faster but not resilient to DoS attacks. |