When a pipeline is created, the set of shaders specified in the corresponding Vk*PipelineCreateInfo structure are implicitly linked at a number of different interfaces
Interface definitions make use of the following SPIR-V decorations
All the variables forming the shader input and output interfaces are listed as operands to the OpEntryPoint instruction and are declared with the Input or Output storage classes, respectively, in the SPIR-V module.
There must be no more than one built-in interface block per shader per interface. Built-ins must not have any Location or Component decorations.
The non-built-in variables listed by OpEntryPoint with the Input or Output storage class form the user-defined variable interface. These variables must be identified with a Location decoration and can also be identified with a Component decoration.Vertex Input Interface Fragment Output Interface
A fragment shader output variable identified with a Location decoration of i is associated with the element of VkRenderingInfo::pColorAttachments with a location equal to i. When using render pass objects, it is associated with the color attachment indicated by pColorAttachments[i]. Values are written to those attachments after passing through the blending unit as described in Blending, if enabled. Locations are consumed as described in Location Assignment. The number of available fragment output locations is given by the maxFragmentOutputAttachments member of the VkPhysicalDeviceLimits structure.Fragment Input Attachment Interface
The fragment shader subpass input variables are matched by InputAttachmentIndex decorations to the input attachments specified in the pInputAttachments array of the VkSubpassDescription structure describing the subpass that the fragment shader is executed in.
A subpass input variable identified with an InputAttachmentIndex decoration of i reads from the input attachment indicated by pInputAttachments[i] member of VkSubpassDescription. If the subpass input variable is declared as an array of size N, it consumes N consecutive input attachments, starting with the index specified. There must not be more than one input variable with the same InputAttachmentIndex whether explicitly declared or implied by an array declaration. The number of available input attachment indices is given by the maxPerStageDescriptorInputAttachments member of the VkPhysicalDeviceLimits structure.Shader Resource Interface
When a shader stage accesses buffer or image resources, as described in the Resource Descriptors section, the shader resource variables must be matched with the pipeline layout that is provided at pipeline creation time.
The set of shader variables that form the shader resource interface for a stage are the variables statically used by that stage’s OpEntryPoint with a storage class of Uniform, UniformConstant, StorageBuffer, or PushConstant. For the fragment shader, this includes the fragment input attachment interface.
The shader resource interface consists of two sub-interfaces: the push constant interface and the descriptor set interface.
Push Constant Interface
Any member of a push constant block that is declared as an array must only be accessed with dynamically uniform indices.
Descriptor Set Interface
The descriptor set interface is comprised of the shader variables with the storage class of StorageBuffer, Uniform or UniformConstant (including the variables in the fragment input attachment interface) that are statically used by the shader entry points for the pipeline.
These variables must have DescriptorSet and Binding decorations specified, which are assigned and matched with the VkDescriptorSetLayout objects in the pipeline layout as described in DescriptorSet and Binding Assignment.
DescriptorSet and Binding Assignment
Offset and Stride AssignmentBuilt-In Variables
Decorating a variable with the DrawIndex built-in will make that variable contain the integer value corresponding to the zero-based index of the drawing command that invoked the current vertex shader invocation. For indirect drawing commands, DrawIndex begins at zero and increments by one for each drawing command executed. The number of drawing commands is given by the drawCount parameter. For direct drawing commands, DrawIndex is always zero. DrawIndex is dynamically uniform.
Decorating a variable with the FragCoord built-in decoration will make that variable contain the framebuffer coordinate 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 z component of FragCoord is the interpolated depth value of the primitive.
To have a shader supply a fragment-depth value, the shader must declare the DepthReplacing execution mode. Such a shader’s fragment-depth value will come from the variable decorated with the FragDepth built-in decoration.This value will be used for any subsequent depth testing performed by the implementation or writes to the depth attachment. See fragment shader depth replacement for details.
Decorating a variable with the FrontFacing built-in decoration will make that variable contain whether the fragment is front or back facing. This variable is non-zero if the current fragment is considered to be part of a front-facing polygon primitive or of a non-polygon primitive and is zero if the fragment is considered to be part of a back-facing polygon primitive.
Decorating a variable with the GlobalInvocationId built-in decoration will make that variable contain 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.
Decorating a variable with the HelperInvocation built-in decoration will make that variable contain whether the current invocation is a helper invocation. This variable is non-zero if the current 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.
Decorating a variable with the InvocationId built-in decoration will make that variable contain the index of the current shader invocation in a geometry shader, or the index of the output patch vertex in a tessellation control shader.
Decorating a variable in a vertex shader with the InstanceIndex built-in decoration will make that variable contain 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.
Decorating a variable with the LocalInvocationId built-in decoration will make that variable contain 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.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.
Decorating a variable with the LocalInvocationIndex built-in decoration will make that variable contain a one-dimensional representation of LocalInvocationId. This is computed as:LocalInvocationIndex =LocalInvocationId.z * WorkgroupSize.x * WorkgroupSize.y +LocalInvocationId.y * WorkgroupSize.x +LocalInvocationId.x;
Decorating a variable with the NumSubgroups built-in decoration will make that variable contain the number of subgroups in the local workgroup.
Decorating a variable with the NumWorkgroups built-in decoration will make that variable contain 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 workgroup count parameters passed into the dispatching commands.
Decorating a variable with the PointCoord built-in decoration will make that variable contain 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 the variable decorated with PointCoord contains an undefined value.
Decorating a variable with the PointSize built-in decoration will make that variable contain the size of point primitives. The value written to the variable decorated with PointSize by the last pre-rasterization shader stage in the pipeline is used as the framebuffer-space size of points produced by rasterization.
The index of the first primitive generated by a drawing command is zero, and the index is incremented after every individual point, line, or triangle primitive is processed.For triangles drawn as points or line segments (see Polygon Mode), the primitive index is incremented only once, even if multiple points or lines are eventually drawn.Variables decorated with PrimitiveId are reset to zero between each instance drawn.Restarting a primitive topology using primitive restart has no effect on the value of variables decorated with PrimitiveId.
Decorating a variable with the SampleId built-in decoration will make that variable contain the coverage index for the current fragment shader invocation. 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, Sample Shading is considered enabled with a minSampleShading value of 1.0.
Decorating a variable with the SamplePosition built-in decoration will make that variable contain 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, Sample Shading is considered enabled with a minSampleShading value of 1.0.
Decorating a variable with the SubgroupId built-in decoration will make that variable contain the index of the subgroup within the local workgroup. This variable is in range [0, NumSubgroups-1].
Decorating a variable with the SubgroupLocalInvocationId builtin decoration will make that variable contain the index of the invocation within the subgroup. This variable is in range [0,SubgroupSize-1].
Decorating a variable with the SubgroupSize builtin decoration will make that variable contain the implementation-dependent number of invocations in a subgroup. This value must be a power-of-two integer.The maximum number of invocations that an implementation can support per subgroup is 128.
Decorating a variable with the VertexIndex built-in decoration will make that variable contain 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 ViewIndex decoration can be applied to a shader input which will be filled with the index of the view that is being processed by the current shader invocation. If multiview is enabled in the render pass, this value will be one of the bits set in the view mask of the subpass the pipeline is compiled against. If multiview is not enabled in the render pass, this value will be zero.
Decorating a variable with the WorkgroupId built-in decoration will make that variable contain the global workgroup that the current invocation is a member of. Each component ranges from a base value to a base + count value, based on the parameters passed into the dispatching commands.
Decorating an object with the WorkgroupSize built-in decoration will make that object contain the dimensions of a local workgroup. If an object is decorated with the WorkgroupSize decoration, this takes precedence over any LocalSize or LocalSizeId execution mode.
原创技术文章，撰写不易，转载请注明出处：电子设备中的画家|王烁 于 2021 年 5 月 10 日发表，原文链接(http://geekfaner.com/shineengine/blog20_Vulkanv1.2_6.html)