14.6. Built-In Variables

Built-in variables are accessed in shaders by declaring a variable decorated using a BuiltIn decoration. The meaning of each BuiltIn decoration is as follows. In the remainder of this section, the name of a built-in is used interchangeably with a term equivalent to a variable decorated with that particular built-in. Built-ins that represent integer values can be declared as either signed or unsigned 32-bit integers.

ClipDistance

Variables decorated with the ClipDistance decoration provide the mechanism for controlling user clipping. Declared as an array, the ith element of the variable decorated as ClipDistance specifies a clip distance for plane i. A clip distance of 0 means the vertex is on the plane, a positive distance means the vertex is inside the clip half-space, and a negative distance means the point is outside the clip half-space.

The ClipDistance array is explicitly sized by the shader.

The ClipDistance decoration can be applied to array inputs in tessellation control, tessellation evaluation and geometry shader stages which will contain the values written by the previous stage. It can be applied to outputs in vertex, tessellation evaluation and geometry shaders. In the last vertex processing stage, these values will be linearly interpolated across the primitive and the portion of the primitive with interpolated distances less than 0 will be considered outside the clip volume.

In the fragment shader, the ClipDistance decoration can be applied to an array of floating-point input variables and contains the linearly interpolated values described above.

ClipDistance must not be used in compute shaders.

ClipDistance must be declared as an array of 32-bit floating-point values.

CullDistance

A variable decorated as CullDistance provides a mechanism for a vertex processing stage to reject an entire primitive. CullDistance can be applied to an array variable. If any member of this array is assigned a negative value for all vertices belonging to a primitive, then the primitive is discarded before rasterization. CullDistance can be applied to an output variable in the last vertex processing stage (vertex, tessellation evaluation or geometry shader).

If applied to an input variable, that variable will contain the corresponding output in the previous shader stage. CullDistance must not be applied to an input in the vertex shader or to an output in the fragment shader, and must not be used in compute shaders.

In fragment shaders, the values of the CullDistance array are linearly interpolated across each primitive.

CullDistance must be declared as an array of 32-bit floating-point values.

FragCoord

This variable contains the framebuffer coordinate $(x,y,z,\frac{1}{w})$ of the fragment being processed. The (x,y) coordinate (0,0) is the upper left corner of the upper left pixel in the framebuffer. The x and y components of FragCoord reflect the location of the center of the pixel ( $(0.5,0.5)$ ) when sample shading is not enabled, and the location of the sample corresponding to the shader invocation when using sample shading.

The z component of FragCoord is the interpolated depth value of the primitive, and the w component is the interpolated $\frac{1}{w}$ .

The FragCoord decoration must be used only within fragment shaders. The Centroid interpolation decoration is ignored on FragCoord.

FragCoord must be declared as a four-component vector of 32-bit floating-point values.

FragDepth

Writing to an output variable decorated with FragDepth from the fragment shader establishes a new depth value for all samples covered by the fragment. This value will be used for depth testing and, if the depth test passes, any subsequent write to the depth/stencil attachment. To write to FragDepth, a shader must declare the DepthReplacing execution mode. If a shader declares the DepthReplacing execution mode and there is an execution path through the shader that does not set FragDepth, then the fragment’s depth value is undefined for executions of the shader that take that path.

The FragDepth decoration must be used only within fragment shaders.

FragDepth must be declared as a scalar 32-bit floating-point value.

FrontFacing

The FrontFacing decoration can be applied to an input variable in the fragment shader. This variable is non-zero if the current fragment is considered to be part of a front-facing primitive and is zero if the fragment is considered to be part of a back-facing primitive.

The FrontFacing decoration is not available to shader stages other than fragment.

FrontFacing must be declared as a scalar 32-bit integer.

[Note]Note

In GLSL, gl_FrontFacing is declared as a bool. To achieve similar semantics in SPIR-V, a variable of OpTypeBool can be declared and initialized as the result of the OpINotEqual operation with the operands of the FrontFacing variable and an appropriately typed constant zero.

GlobalInvocationId

The GlobalInvocationId built-in decoration can be applied to a variable that represents the location of the current invocation within the global workgroup. Each component is equal to the index of the local workgroup multiplied by the size of the local workgroup plus LocalInvocationId.

The GlobalInvocationId decoration must be used only within compute shaders.

The variable decorated with GlobalInvocationId must be declared using the input storage class.

The variable decorated with GlobalInvocationId must be declared as a three-component vector of 32-bit unsigned integers.

HelperInvocation

This variable is non-zero if the fragment being shaded is a helper invocation and zero otherwise. A helper invocation is an invocation of the shader that is produced to satisfy internal requirements such as the generation of derivatives.

The HelperInvocation decoration must be used only within fragment shaders.

HelperInvocation must be declared as a scalar 32-bit integer.

[Note]Note

It is very likely that a helper invocation will have a value of SampleMask fragment shader input value that is zero.

[Note]Note

In GLSL, HelperInvocation is declared as a bool. To achieve similar semantics in SPIR-V, a variable of OpTypeBool can be declared and initialized as the result of the OpINotEqual operation with the operands of the HelperInvocation variable and an appropriately typed constant zero.

InvocationId

In a geometry shader, an input variable decorated with the InvocationId decoration contains the index of the current shader invocation, which ranges from zero to the number of instances declared in the shader minus one. If the instance count of the geometry shader is one or is not specified, then InvocationId will be zero.

In tessellation control shaders, and input variable decorated with the InvocationId decoration contains the index of the output patch vertex assigned to the tessellation control shader invocation.

The InvocationId decoration must not be used in vertex, tessellation evaluation, fragment, or compute shaders.

InvocationId must be declared as a scalar 32-bit integer.

InstanceIndex

The InstanceIndex decoration can be applied to a vertex shader input which will be filled with the index of the instance that is being processed by the current vertex shader invocation. InstanceIndex begins at the firstInstance parameter to vkCmdDraw or vkCmdDrawIndexed or at the firstInstance member of a structure consumed by vkCmdDrawIndirect or vkCmdDrawIndexedIndirect.

The InstanceIndex decoration must not be used in any shader stage other than vertex.

InstanceIndex must be declared as a scalar 32-bit integer.

Layer

The Layer decoration can be applied to an output variable in the geometry shader that is written with the framebuffer layer index to which the primitive produced by the geometry shader will be directed. If a geometry shader entry point’s interface does not include an output variable decorated with Layer, then the first layer is used. If a geometry shader entry point’s interface includes an output variable decorated with Layer, it must write the same value to Layer for all output vertices of a given primitive. When used in a fragment shader, an input variable decorated with Layer contains the layer index of the primitive that the fragment invocation belongs to.

The Layer decoration must be used only within geometry and fragment shaders.

Layer must be declared as a scalar 32-bit integer.

LocalInvocationId

The LocalInvocationId built-in decoration can be applied to a variable that represents the location of the current compute shader invocation within the local workgroup. Each component ranges from zero through to the size of the workgroup in that dimension minus one.

The LocalInvocationId decoration must be used only within compute shaders.

The variable decorated with LocalInvocationId must be declared using the input storage class.

The variable decorated with LocalInvocationId must be declared as a three-component vector of 32-bit unsigned integers.

[Note]Note

If the size of the workgroup in a particular dimension is one, then the LocalInvocationId in that dimension will be zero. If the workgroup is effectively two-dimensional, then LocalInvocationId.z will be zero. If the workgroup is effectively one-dimensional, then both LocalInvocationId.y and LocalInvocationId.z will be zero.

NumWorkgroups

The NumWorkgroups built-in decoration can be applied to a variable that represents the number of local workgroups that are part of the dispatch that the invocation belongs to. Each component is equal to the values of the parameters passed into vkCmdDispatch or read from the VkDispatchIndirectCommand structure read through a call to vkCmdDispatchIndirect.

The NumWorkgroups decoration must be used only within compute shaders.

The variable decorated with NumWorkgroups must be declared using the input storage class.

The variable decorated with NumWorkgroups must be declared as a three-component vector of 32-bit integers.

PatchVertices

An input variable decorated with PatchVertices in the tessellation control or evaluation shader is an integer specifying the number of vertices in the input patch being processed by the shader. A single tessellation control or evaluation shader can read patches of differing sizes, so the PatchVertices variable may differ between patches.

The PatchVertices decoration must be used only within tessellation control and evaluation shaders.

PatchVertices must be declared as scalar 32-bit integer.

PointCoord

During point rasterization, a variable decorated with PointCoord contains the coordinate of the current fragment within the point being rasterized, normalized to the size of the point with origin in the upper left corner of the point, as described in Basic Point Rasterization. If the primitive the fragment shader invocation belongs to is not a point, then PointCoord is undefined.

The PointCoord decoration must be used only within fragment shaders.

PointCoord must be declared as two-component vector of 32-bit floating-point values.

[Note]Note

Depending on how the point is rasterized, PointCoord may never reach (0,0) or (1,1).

PointSize

The PointSize built-in decoration is used to pass the size of point primitives between shader stages. It can be applied to inputs to tessellation control and geometry shaders. It can be applied to output variables in vertex, tessellation evaluation and geometry shaders. The value written to the variable decorated as PointSize by the last vertex processing stage in the pipeline is used as the framebuffer space size of points produced by rasterization. As an input, it reflects the value written to the output decorated with PointSize in the previous shader stage.

The PointSize decoration must not be applied to inputs in the vertex shader and must not be used in fragment or compute shaders.

PointSize must be declared as a scalar 32-bit floating-point value.

Position

The Position built-in decoration can be used on variables declared as input to tessellation control, tessellation evaluation and geometry shaders. It can be used on variables declared as outputs in the vertex, tessellation control, tessellation evaluation and geometry shaders. As an input, it contains the data written to the output variable decorated as Position in the previous shader stage. As an output, the data written to a variable decorated as Position is passed to the next shader stage. In the last vertex processing stage, the output position is used in subsequent primitive assembly, clipping and rasterization operations.

Variables decorated as Position must not be used as inputs in vertex shaders and must not be used in fragment or compute shaders.

Position must be declared as a four-component vector of 32-bit floating-point values.

PrimitiveId

When the PrimitiveId decoration is applied to an input variable in the tessellation control or tessellation evaluation shader, it will be filled with the index of the patch within the current set of rendering primitives that corresponds to the shader invocation.

When the PrimitiveId decoration is applied to an input variable in the geometry shader, it will be filled with the number of primitives presented as input to the geometry shader since the current set of rendering primitives was started. When PrimitiveId is applied to an output in the geometry shader, the resulting value is seen as an input to the fragment shader.

When PrimitiveId is applied to an input in the fragment shader, it will be filled with the primitive index written by the geometry shader if a geometry shader is present, or with the value that would have been presented as input to the geometry shader had it been present. If a geometry shader is present and the fragment shader reads from an input variable decorated with PrimitiveId, then the geometry shader must write to an output variable decorated with PrimitiveId in all execution paths; otherwise the PrimitiveId input in the fragment shader is undefined.

The PrimitiveId decoration must not be used in vertex or compute shaders. PrimitiveId must not be used on output variables in tessellation control, tessellation evaluation, or fragment shaders.

PrimitiveId must be declared as scalar 32-bit integer.

SampleId

The SampleId decoration can be applied to an integer input variable in the fragment shader. This variable will contain the zero-based index of the sample the invocation corresponds to. SampleId ranges from zero to the number of samples in the framebuffer minus one. If a fragment shader entry point’s interface includes an input variable decorated with SampleId, per-sample shading is enabled for draws that use that fragment shader.

SampleId is not available in shader stages other than fragment.

SampleId must be declared as a scalar 32-bit integer.

SampleMask

A fragment input variable decorated with SampleMask will contain a bitmask of the set of samples covered by the primitive generating the fragment during rasterization. It has a sample bit set if and only if the sample is considered covered for this fragment shader invocation. SampleMask[] is an array of integers. Bits are mapped to samples in a manner where bit B of mask M (SampleMask[M]) corresponds to sample $32 \times M + B$ .

When state specifies multiple fragment shader invocations for a given fragment, the sample mask for any single fragment shader invocation specifies the subset of the covered samples for the fragment that correspond to the invocation. In this case, the bit corresponding to each covered sample will be set in exactly one fragment shader invocation.

A fragment output variable decorated with SampleMask is an array of integers forming a bit array in a manner similar an input variable decorated with SampleMask, but where each bit represents coverage as computed by the shader. Modifying the sample mask by writing zero to a bit of SampleMask causes the sample to be considered uncovered. However, setting sample mask bits to one will never enable samples not covered by the original primitive. If the fragment shader is being evaluated at any frequency other than per-fragment, bits of the sample mask not corresponding to the current fragment shader invocation are ignored. This array must be sized in the fragment shader either implicitly or explicitly, to be no larger than the implementation-dependent maximum sample-mask (as an array of 32-bit elements), determined by the maximum number of samples. If a fragment shader entry point’s interface includes an output variable decorated with SampleMask, the sample mask will be undefined for any array elements of any fragment shader invocations that fail to assign a value. If a fragment shader entry point’s interface does not include an output variable decorated with SampleMask, the sample mask has no effect on the processing of a fragment.

The SampleMask decoration must be used only within fragment shaders.

SampleMask must be declared as an array of 32-bit integers.

SamplePosition

This variable contains the sub-pixel position of the sample being shaded. The top left of the pixel is considered to be at coordinate (0,0) and the bottom right of the pixel is considered to be at coordinate (1,1). If a fragment shader entry point’s interface includes an input variable decorated with SamplePosition, per-sample shading is enabled for draws that use that fragment shader.

The SamplePosition decoration must be used only within fragment shaders.

SamplePosition must be declared as a two-component vector of floating-point values.

TessCoord

The TessCoord is applied to an input variable in tessellation evaluation shaders and specifies the three-dimensional (u,v,w) barycentric coordinate of the tessellated vertex within the patch. u, v, and w are in the range $[0,1]$ and vary linearly across the primitive being subdivided. For the tessellation modes of Quads or IsoLines, the third component is always zero.

The TessCoord decoration must be used only within tessellation evaluation shaders.

TessCoord must be declared as three-component vector of 32-bit floating-point values.

TessLevelOuter

The TessLevelOuter decoration is used in tessellation control shaders to decorate an output variable to contain the outer tessellation factors for the resulting patch. These values are used by the tessellator to control primitive tessellation and can be read by tessellation evaluation shaders. When applied to an input variable in a tessellation evaluation shader, the shader can read the values written by the tessellation control shader.

The TessLevelOuter decoration must be used only within tessellation control and evaluation shaders.

TessLevelOuter must be declared as an array of size four, containing 32-bit floating-point values.

TessLevelInner

The TessLevelInner decoration is used in tessellation control shaders to decorate an output variable to contain the inner tessellation factors for the resulting patch. These values are used by the tessellator to control primitive tessellation and can be read by tessellation evaluation shaders. When applied to an input variable in a tessellation evaluation shader, the shader can read the values written by the tessellation control shader.

The TessLevelInner decoration must be used only within tessellation control and evaluation shaders.

TessLevelInner must be declared as an array of size two, containing 32-bit floating-point values.

VertexIndex

The VertexIndex decoration can be applied to a vertex shader input which will be filled with the index of the vertex that is being processed by the current vertex shader invocation. For non-indexed draws, this variable begins at the firstVertex parameter to vkCmdDraw or the firstVertex member of a structure consumed by vkCmdDrawIndirect and increments by one for each vertex in the draw. For indexed draws, its value is the content of the index buffer for the vertex plus the vertexOffset parameter to vkCmdDrawIndexed or the vertexOffset member of the structure consumed by vkCmdDrawIndexedIndirect.

VertexIndex starts at the same starting value for each instance.

The VertexIndex decoration must be used only within vertex shaders.

VertexIndex must be declared as a 32-bit integer.

ViewportIndex

The ViewportIndex decoration can be applied to an output variable in the geometry shader that is written with the viewport index to which the primitive produced by the geometry shader will be directed. The selected viewport index is used to select the viewport transform and scissor rectangle. If a geometry shader entry point’s interface does not include an output variable decorated with ViewportIndex, then the first viewport is used. If a geometry shader entry point’s interface includes an output variable decorated with ViewportIndex, it must write the same value to ViewportIndex for all output vertices of a given primitive. When used in a fragment shader, an input variable decorated with ViewportIndex contains the viewport index of the primitive that the fragment invocation belongs to.

The ViewportIndex decoration must be used only within geometry and fragment shaders.

ViewportIndex must be declared as a 32-bit integer.

WorkgroupId

The WorkgroupId built-in decoration can be applied to a variable that represents the global workgroup that the current invocation is a member of. Each component ranges from zero to the values of the parameters passed into vkCmdDispatch or read from the VkDispatchIndirectCommand structure read through a call to vkCmdDispatchIndirect.

The WorkgroupId decoration must be used only within compute shaders.

The variable decorated with WorkgroupId must be declared using the input storage class.

The variable decorated with WorkgroupId must be declared as a three-component vector of 32-bit unsigned integers.

WorkgroupSize

The WorkgroupSize built-in decoration can be applied to an object that represents the dimensions of a local workgroup. If an object is decorated with the WorkgroupSize decoration, this must take precedence over any execution mode set for LocalSize.

The WorkgroupSize decoration must be used only within compute shaders.

The object decorated with WorkgroupSize must be a specialization constant or a constant.

The object decorated with WorkgroupSize must be declared as a three-component vector of 32-bit unsigned integers.