Semantic Signatures#
Overview#
A semantic signature describes the inputs and outputs of an HLSL shader entry
point: the semantics each value carries, its component type, and where it is
placed in the input/output register space. The DirectX Container (DXContainer)
stores this information in binary signature parts (ISG1, OSG1) and in the
pipeline state validation part (PSV0). To assist with the construction of, and
interaction with, these parts, a semantic signature is represented as metadata
(dx.semantic.signatures) in the LLVM IR. The metadata can then be converted to
its binary form, as defined in SemanticSignatures.h. This document serves as a
reference for the metadata representation of a semantic signature for users to
interface with.
Metadata Representation#
Consider the reference shaders below, then the following sections describe the metadata representation of their signatures and the corresponding operands.
float4 vs_main(float4 pos : POSITION,
float4 uv[2] : TEXCOORD0) : SV_Position {
return pos + uv[0] + uv[1];
}
struct PSOut {
float4 color : SV_Target0;
float4 extra : SV_Target1;
};
PSOut ps_main(float4 pos : SV_Position,
float4 uv0 : TEXCOORD0,
float4 uv1 : TEXCOORD1) {
PSOut o;
o.color = pos + uv0;
o.extra = float4(uv1.xyz, 1);
return o;
}
Note: A signature does not necessarily have a unique metadata representation. Further, a malformed signature can be represented in the metadata format, and so it is the user’s responsibility to verify that it is a well-formed signature.
Named Signature Table#
!dx.semantic.signatures = !{!1, !2}
A named metadata node, dx.semantic.signatures, is used to identify the table
of per-entry-point semantic signatures. The table itself is a list of references
to function/signature triples. If no entry point has a signature, the named
metadata node may be omitted entirely.
Function/Signature Triple#
!1 = !{ ptr @vs_main, !3, !4 }
The function/signature triple associates an entry-point function (the first
operand) with its input signature element list (the second operand) and output
signature element list (the third operand). Either list may be null. An entry
function may appear at most once.
Signature Element List#
!3 = !{ !5, !6 }
A signature element list consists of a list of references to signature element nodes.
Signature Element#
!5 = !{ i32 0, !"TEXCOORD", i32 9, i32 0, !50, i32 0, i32 1, i8 4, i32 0, i8 0, i8 0, i8 0, i32 0 }
A signature element describes a single packed range of signature rows. It
retains all information needed to serialize into ISG1, OSG1 and PSV0.
Name |
Type |
Description |
|---|---|---|
Signature ID |
i32 |
dense 0-based index within the entry function signature list; matches the operand of |
Semantic Name |
metadata string |
the semantic name (e.g. |
Component Type |
i32 |
component type; see |
Semantic Kind |
i32 |
semantic kind; |
Semantic Indices |
metadata node |
reference to a semantic indices node |
Interpolation Mode |
i32 |
interpolation mode; see |
Rows |
i32 |
number of consecutive register rows occupied |
Cols |
i8 |
number of components per row (1–4) |
Start Row |
i32 |
starting register row; |
Start Column |
i8 |
starting component column; |
Usage Mask |
i8 |
4-bit bitmask of components that are always read (input) or may be written (output). |
Dynamic Index Mask |
i8 |
4-bit bitmask of components that are dynamically indexed |
GS Output Stream Index |
i32 |
GS output stream index; 0 for non-GS stages |
Derived Container Fields#
The following container fields are derived from the operands above:
Allocated: allocated iff
StartRow != -1andStartCol != -1(the sentinels are always set together).DeclaredMask:
((1 << Cols) - 1) << StartCol.AlwaysReads / NeverWrites:
UsageMaskis written toAlwaysReadsfor inputs; for outputsNeverWrites = ~UsageMask & DeclaredMask.MinPrecision: from
CompTypeplus theUseMinPrecisionmodule flag.
Semantic Indices#
!50 = !{ i32 0 }
!51 = !{ i32 0, i32 1 }
A metadata node of one or more semantic indices. Its length must equal the
Rows field of the containing signature element.