| // Copyright 2015-2023 The Khronos Group Inc. |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| [[fxvertex]] |
| = Fixed-Function Vertex Processing |
| |
| Vertex fetching is controlled via configurable state, as a logically |
| distinct graphics pipeline stage. |
| |
| |
| [[fxvertex-attrib]] |
| == Vertex Attributes |
| |
| Vertex shaders can: define input variables, which receive _vertex attribute_ |
| data transferred from one or more sname:VkBuffer(s) by drawing commands. |
| Vertex shader input variables are bound to buffers via an indirect binding |
| where the vertex shader associates a _vertex input attribute_ number with |
| each variable, vertex input attributes are associated to _vertex input |
| bindings_ on a per-pipeline basis, and vertex input bindings are associated |
| with specific buffers on a per-draw basis via the |
| fname:vkCmdBindVertexBuffers command. |
| Vertex input attribute and vertex input binding descriptions also contain |
| format information controlling how data is extracted from buffer memory and |
| converted to the format expected by the vertex shader. |
| |
| There are sname:VkPhysicalDeviceLimits::pname:maxVertexInputAttributes |
| number of vertex input attributes and |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings number of vertex |
| input bindings (each referred to by zero-based indices), where there are at |
| least as many vertex input attributes as there are vertex input bindings. |
| Applications can: store multiple vertex input attributes interleaved in a |
| single buffer, and use a single vertex input binding to access those |
| attributes. |
| |
| In GLSL, vertex shaders associate input variables with a vertex input |
| attribute number using the code:location layout qualifier. |
| The code:Component layout qualifier associates components of a vertex shader |
| input variable with components of a vertex input attribute. |
| |
| .GLSL example |
| [source,glsl] |
| ---- |
| // Assign location M to variableName |
| layout (location=M, component=2) in vec2 variableName; |
| |
| // Assign locations [N,N+L) to the array elements of variableNameArray |
| layout (location=N) in vec4 variableNameArray[L]; |
| ---- |
| |
| In SPIR-V, vertex shaders associate input variables with a vertex input |
| attribute number using the code:Location decoration. |
| The code:Component decoration associates components of a vertex shader input |
| variable with components of a vertex input attribute. |
| The code:Location and code:Component decorations are specified via the |
| code:OpDecorate instruction. |
| |
| .SPIR-V example |
| [source,spirv] |
| ---- |
| ... |
| %1 = OpExtInstImport "GLSL.std.450" |
| ... |
| OpName %9 "variableName" |
| OpName %15 "variableNameArray" |
| OpDecorate %18 BuiltIn VertexIndex |
| OpDecorate %19 BuiltIn InstanceIndex |
| OpDecorate %9 Location M |
| OpDecorate %9 Component 2 |
| OpDecorate %15 Location N |
| ... |
| %2 = OpTypeVoid |
| %3 = OpTypeFunction %2 |
| %6 = OpTypeFloat 32 |
| %7 = OpTypeVector %6 2 |
| %8 = OpTypePointer Input %7 |
| %9 = OpVariable %8 Input |
| %10 = OpTypeVector %6 4 |
| %11 = OpTypeInt 32 0 |
| %12 = OpConstant %11 L |
| %13 = OpTypeArray %10 %12 |
| %14 = OpTypePointer Input %13 |
| %15 = OpVariable %14 Input |
| ... |
| ---- |
| |
| |
| [[fxvertex-attrib-location]] |
| === Attribute Location and Component Assignment |
| |
| The code:Location decoration specifies which vertex input attribute is used |
| to read and interpret the data that a variable will consume. |
| |
| When a vertex shader input variable declared using a 16- or 32-bit scalar or |
| vector data type is assigned a code:Location, its value(s) are taken from |
| the components of the input attribute specified with the corresponding |
| sname:VkVertexInputAttributeDescription::pname:location. |
| The components used depend on the type of variable and the code:Component |
| decoration specified in the variable declaration, as identified in |
| <<fxvertex-attrib-components>>. |
| Any 16-bit or 32-bit scalar or vector input will consume a single |
| code:Location. |
| For 16-bit and 32-bit data types, missing components are filled in with |
| default values as described <<fxvertex-input-extraction,below>>. |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_16bit_storage[] |
| If an implementation supports <<features-storageInputOutput16, |
| pname:storageInputOutput16>>, vertex shader input variables can: have a |
| width of 16 bits. |
| endif::VK_VERSION_1_1,VK_KHR_16bit_storage[] |
| |
| [[fxvertex-attrib-components]] |
| .Input attribute components accessed by 16-bit and 32-bit input variables |
| [width="65%",cols="<5,<3,<3",options="header"] |
| |==== |
| | 16-bit or 32-bit data type | code:Component decoration | Components consumed |
| | scalar | 0 or unspecified | (x, o, o, o) |
| | scalar | 1 | (o, y, o, o) |
| | scalar | 2 | (o, o, z, o) |
| | scalar | 3 | (o, o, o, w) |
| | two-component vector | 0 or unspecified | (x, y, o, o) |
| | two-component vector | 1 | (o, y, z, o) |
| | two-component vector | 2 | (o, o, z, w) |
| | three-component vector | 0 or unspecified | (x, y, z, o) |
| | three-component vector | 1 | (o, y, z, w) |
| | four-component vector | 0 or unspecified | (x, y, z, w) |
| |==== |
| |
| Components indicated by "`o`" are available for use by other input variables |
| which are sourced from the same attribute, and if used, are either filled |
| with the corresponding component from the input format (if present), or the |
| default value. |
| |
| When a vertex shader input variable declared using a 32-bit floating point |
| matrix type is assigned a code:Location _i_, its values are taken from |
| consecutive input attributes starting with the corresponding |
| sname:VkVertexInputAttributeDescription::pname:location. |
| Such matrices are treated as an array of column vectors with values taken |
| from the input attributes identified in <<fxvertex-attrib-matrix>>. |
| The sname:VkVertexInputAttributeDescription::pname:format must: be specified |
| with a elink:VkFormat that corresponds to the appropriate type of column |
| vector. |
| The code:Component decoration must: not be used with matrix types. |
| |
| [[fxvertex-attrib-matrix]] |
| .Input attributes accessed by 32-bit input matrix variables |
| [width="100%",cols="<10%,<24%,<21%,<45%",options="header"] |
| |==== |
| | Data type | Column vector type | Locations consumed | Components consumed |
| | mat2 | two-component vector | i, i+1 | (x, y, o, o), (x, y, o, o) |
| | mat2x3 | three-component vector | i, i+1 | (x, y, z, o), (x, y, z, o) |
| | mat2x4 | four-component vector | i, i+1 | (x, y, z, w), (x, y, z, w) |
| | mat3x2 | two-component vector | i, i+1, i+2 | (x, y, o, o), (x, y, o, o), (x, y, o, o) |
| | mat3 | three-component vector | i, i+1, i+2 | (x, y, z, o), (x, y, z, o), (x, y, z, o) |
| | mat3x4 | four-component vector | i, i+1, i+2 | (x, y, z, w), (x, y, z, w), (x, y, z, w) |
| | mat4x2 | two-component vector | i, i+1, i+2, i+3 | (x, y, o, o), (x, y, o, o), (x, y, o, o), (x, y, o, o) |
| | mat4x3 | three-component vector | i, i+1, i+2, i+3 | (x, y, z, o), (x, y, z, o), (x, y, z, o), (x, y, z, o) |
| | mat4 | four-component vector | i, i+1, i+2, i+3 | (x, y, z, w), (x, y, z, w), (x, y, z, w), (x, y, z, w) |
| |==== |
| |
| Components indicated by "`o`" are available for use by other input variables |
| which are sourced from the same attribute, and if used, are either filled |
| with the corresponding component from the input (if present), or the default |
| value. |
| |
| When a vertex shader input variable declared using a scalar or vector 64-bit |
| data type is assigned a code:Location _i_, its values are taken from |
| consecutive input attributes starting with the corresponding |
| sname:VkVertexInputAttributeDescription::pname:location. |
| The code:Location slots and code:Component words used depend on the type of |
| variable and the code:Component decoration specified in the variable |
| declaration, as identified in <<fxvertex-attrib-double>>. |
| For 64-bit data types, no default attribute values are provided. |
| Input variables must: not use more components than provided by the |
| attribute. |
| |
| [[fxvertex-attrib-double]] |
| .Input attribute locations and components accessed by 64-bit input variables |
| [width="100%",cols="<18%,^12%,<25%,^14%,^18%,<13%",options="header"] |
| |==== |
| ^.^| Input format | Locations consumed |
| ^.^| 64-bit data type |code:Location decoration |code:Component decoration ^| 32-bit components consumed |
| | R64 | i |
| | scalar | i | 0 or unspecified | (x, y, -, -) |
| .3+<.^| R64G64 .3+^.^| i |
| | scalar | i | 0 or unspecified | (x, y, o, o) |
| | scalar | i | 2 | (o, o, z, w) |
| | two-component vector | i | 0 or unspecified | (x, y, z, w) |
| .5+<.^| R64G64B64 .5+^.^| i, i+1 |
| | scalar | i | 0 or unspecified | (x, y, o, o), (o, o, -, -) |
| | scalar | i | 2 | (o, o, z, w), (o, o, -, -) |
| | scalar | i+1 | 0 or unspecified | (o, o, o, o), (x, y, -, -) |
| | two-component vector | i | 0 or unspecified | (x, y, z, w), (o, o, -, -) |
| | three-component vector | i | unspecified | (x, y, z, w), (x, y, -, -) |
| .8+<.^| R64G64B64A64 .8+^.^| i, i+1 |
| | scalar | i | 0 or unspecified | (x, y, o, o), (o, o, o, o) |
| | scalar | i | 2 | (o, o, z, w), (o, o, o, o) |
| | scalar | i+1 | 0 or unspecified | (o, o, o, o), (x, y, o, o) |
| | scalar | i+1 | 2 | (o, o, o, o), (o, o, z, w) |
| | two-component vector | i | 0 or unspecified | (x, y, z, w), (o, o, o, o) |
| | two-component vector | i+1 | 0 or unspecified | (o, o, o, o), (x, y, z, w) |
| | three-component vector | i | unspecified | (x, y, z, w), (x, y, o, o) |
| | four-component vector | i | unspecified | (x, y, z, w), (x, y, z, w) |
| |==== |
| |
| Components indicated by "`o`" are available for use by other input variables |
| which are sourced from the same attribute. |
| Components indicated by "`-`" are not available for input variables as there |
| are no default values provided for 64-bit data types, and there is no data |
| provided by the input format. |
| |
| When a vertex shader input variable declared using a 64-bit floating-point |
| matrix type is assigned a code:Location _i_, its values are taken from |
| consecutive input attribute locations. |
| Such matrices are treated as an array of column vectors with values taken |
| from the input attributes as shown in <<fxvertex-attrib-double>>. |
| Each column vector starts at the code:Location immediately following the |
| last code:Location of the previous column vector. |
| The number of attributes and components assigned to each matrix is |
| determined by the matrix dimensions and ranges from two to eight locations. |
| |
| When a vertex shader input variable declared using an array type is assigned |
| a location, its values are taken from consecutive input attributes starting |
| with the corresponding |
| sname:VkVertexInputAttributeDescription::pname:location. |
| The number of attributes and components assigned to each element are |
| determined according to the data type of the array elements and |
| code:Component decoration (if any) specified in the declaration of the |
| array, as described above. |
| Each element of the array, in order, is assigned to consecutive locations, |
| but all at the same specified component within each location. |
| |
| Only input variables declared with the data types and component decorations |
| as specified above are supported. |
| Two variables are allowed to share the same code:Location slot only if their |
| code:Component words do not overlap. |
| If multiple variables share the same code:Location slot, they must: all have |
| the same SPIR-V floating-point component type or all have the same width |
| scalar type components. |
| |
| [[fxvertex-input]] |
| == Vertex Input Description |
| |
| Applications specify vertex input attribute and vertex input binding |
| descriptions as part of graphics pipeline creation by setting the |
| slink:VkGraphicsPipelineCreateInfo::pname:pVertexInputState pointer to a |
| slink:VkPipelineVertexInputStateCreateInfo structure. |
| ifdef::VK_EXT_vertex_input_dynamic_state[] |
| Alternatively, if the graphics pipeline is created with the |
| ename:VK_DYNAMIC_STATE_VERTEX_INPUT_EXT dynamic state enabled, then the |
| vertex input attribute and vertex input binding descriptions are specified |
| dynamically with flink:vkCmdSetVertexInputEXT, and the |
| slink:VkGraphicsPipelineCreateInfo::pname:pVertexInputState pointer is |
| ignored. |
| endif::VK_EXT_vertex_input_dynamic_state[] |
| |
| [open,refpage='VkPipelineVertexInputStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline vertex input state',type='structs'] |
| -- |
| The sname:VkPipelineVertexInputStateCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkPipelineVertexInputStateCreateInfo.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is reserved for future use. |
| * pname:vertexBindingDescriptionCount is the number of vertex binding |
| descriptions provided in pname:pVertexBindingDescriptions. |
| * pname:pVertexBindingDescriptions is a pointer to an array of |
| sname:VkVertexInputBindingDescription structures. |
| * pname:vertexAttributeDescriptionCount is the number of vertex attribute |
| descriptions provided in pname:pVertexAttributeDescriptions. |
| * pname:pVertexAttributeDescriptions is a pointer to an array of |
| sname:VkVertexInputAttributeDescription structures. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineVertexInputStateCreateInfo-vertexBindingDescriptionCount-00613]] |
| pname:vertexBindingDescriptionCount must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-VkPipelineVertexInputStateCreateInfo-vertexAttributeDescriptionCount-00614]] |
| pname:vertexAttributeDescriptionCount must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputAttributes |
| * [[VUID-VkPipelineVertexInputStateCreateInfo-binding-00615]] |
| For every pname:binding specified by each element of |
| pname:pVertexAttributeDescriptions, a |
| sname:VkVertexInputBindingDescription must: exist in |
| pname:pVertexBindingDescriptions with the same value of pname:binding |
| * [[VUID-VkPipelineVertexInputStateCreateInfo-pVertexBindingDescriptions-00616]] |
| All elements of pname:pVertexBindingDescriptions must: describe distinct |
| binding numbers |
| * [[VUID-VkPipelineVertexInputStateCreateInfo-pVertexAttributeDescriptions-00617]] |
| All elements of pname:pVertexAttributeDescriptions must: describe |
| distinct attribute locations |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineVertexInputStateCreateInfo.adoc[] |
| -- |
| |
| [open,refpage='VkPipelineVertexInputStateCreateFlags',desc='Reserved for future use',type='flags'] |
| -- |
| include::{generated}/api/flags/VkPipelineVertexInputStateCreateFlags.adoc[] |
| |
| tname:VkPipelineVertexInputStateCreateFlags is a bitmask type for setting a |
| mask, but is currently reserved for future use. |
| -- |
| |
| [open,refpage='VkVertexInputBindingDescription',desc='Structure specifying vertex input binding description',type='structs'] |
| -- |
| Each vertex input binding is specified by the |
| sname:VkVertexInputBindingDescription structure, defined as: |
| |
| include::{generated}/api/structs/VkVertexInputBindingDescription.adoc[] |
| |
| * pname:binding is the binding number that this structure describes. |
| * pname:stride is the byte stride between consecutive elements within the |
| buffer. |
| * pname:inputRate is a elink:VkVertexInputRate value specifying whether |
| vertex attribute addressing is a function of the vertex index or of the |
| instance index. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkVertexInputBindingDescription-binding-00618]] |
| pname:binding must: be less than |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-VkVertexInputBindingDescription-stride-00619]] |
| pname:stride must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindingStride |
| ifdef::VK_KHR_portability_subset[] |
| * [[VUID-VkVertexInputBindingDescription-stride-04456]] |
| If the `apiext:VK_KHR_portability_subset` extension is enabled, |
| pname:stride must: be a multiple of, and at least as large as, |
| slink:VkPhysicalDevicePortabilitySubsetPropertiesKHR::pname:minVertexInputBindingStrideAlignment |
| endif::VK_KHR_portability_subset[] |
| **** |
| |
| include::{generated}/validity/structs/VkVertexInputBindingDescription.adoc[] |
| -- |
| |
| [open,refpage='VkVertexInputRate',desc='Specify rate at which vertex attributes are pulled from buffers',type='enums'] |
| -- |
| Possible values of slink:VkVertexInputBindingDescription::pname:inputRate, |
| specifying the rate at which vertex attributes are pulled from buffers, are: |
| |
| include::{generated}/api/enums/VkVertexInputRate.adoc[] |
| |
| * ename:VK_VERTEX_INPUT_RATE_VERTEX specifies that vertex attribute |
| addressing is a function of the vertex index. |
| * ename:VK_VERTEX_INPUT_RATE_INSTANCE specifies that vertex attribute |
| addressing is a function of the instance index. |
| -- |
| |
| [open,refpage='VkVertexInputAttributeDescription',desc='Structure specifying vertex input attribute description',type='structs'] |
| -- |
| Each vertex input attribute is specified by the |
| sname:VkVertexInputAttributeDescription structure, defined as: |
| |
| include::{generated}/api/structs/VkVertexInputAttributeDescription.adoc[] |
| |
| * pname:location is the shader input location number for this attribute. |
| * pname:binding is the binding number which this attribute takes its data |
| from. |
| * pname:format is the size and type of the vertex attribute data. |
| * pname:offset is a byte offset of this attribute relative to the start of |
| an element in the vertex input binding. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkVertexInputAttributeDescription-location-00620]] |
| pname:location must: be less than |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputAttributes |
| * [[VUID-VkVertexInputAttributeDescription-binding-00621]] |
| pname:binding must: be less than |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-VkVertexInputAttributeDescription-offset-00622]] |
| pname:offset must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputAttributeOffset |
| * [[VUID-VkVertexInputAttributeDescription-format-00623]] |
| The <<resources-buffer-view-format-features,format features>> of |
| pname:format must: contain ename:VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
| ifdef::VK_KHR_portability_subset[] |
| * [[VUID-VkVertexInputAttributeDescription-vertexAttributeAccessBeyondStride-04457]] |
| If the `apiext:VK_KHR_portability_subset` extension is enabled, and |
| slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:vertexAttributeAccessBeyondStride |
| is ename:VK_FALSE, the sum of pname:offset plus the size of the vertex |
| attribute data described by pname:format must: not be greater than |
| pname:stride in the slink:VkVertexInputBindingDescription referenced in |
| pname:binding |
| endif::VK_KHR_portability_subset[] |
| **** |
| |
| include::{generated}/validity/structs/VkVertexInputAttributeDescription.adoc[] |
| -- |
| |
| ifdef::VK_EXT_vertex_input_dynamic_state,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetVertexInputEXT',desc='Set the vertex input state dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the vertex input attribute |
| and vertex input binding descriptions, call: |
| |
| include::{generated}/api/protos/vkCmdSetVertexInputEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:vertexBindingDescriptionCount is the number of vertex binding |
| descriptions provided in pname:pVertexBindingDescriptions. |
| * pname:pVertexBindingDescriptions is a pointer to an array of |
| sname:VkVertexInputBindingDescription2EXT structures. |
| * pname:vertexAttributeDescriptionCount is the number of vertex attribute |
| descriptions provided in pname:pVertexAttributeDescriptions. |
| * pname:pVertexAttributeDescriptions is a pointer to an array of |
| sname:VkVertexInputAttributeDescription2EXT structures. |
| |
| This command sets the vertex input attribute and vertex input binding |
| descriptions state for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_vertex_input_dynamic_state[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_vertex_input_dynamic_state[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_vertex_input_dynamic_state[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_VERTEX_INPUT_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_vertex_input_dynamic_state[] |
| Otherwise, this state is specified by the |
| slink:VkGraphicsPipelineCreateInfo::pname:pVertexInputState values used to |
| create the currently active pipeline. |
| |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| If |
| ifdef::VK_EXT_shader_object[] |
| drawing using <<shaders-objects, shader objects>>, |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[or if] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| the bound pipeline state object was also created with the |
| ename:VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE dynamic state enabled, |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| then flink:vkCmdBindVertexBuffers2 can be used instead of |
| fname:vkCmdSetVertexInputEXT to dynamically set the stride. |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| .Valid Usage |
| **** |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_vertex_input_dynamic_state[] |
| * [[VUID-vkCmdSetVertexInputEXT-None-08546]] |
| Either the <<features-vertexInputDynamicState, |
| pname:vertexInputDynamicState>> feature or the <<features-shaderObject, |
| pname:shaderObject>> feature or both must: be enabled |
| endif::VK_EXT_vertex_input_dynamic_state[] |
| ifndef::VK_EXT_vertex_input_dynamic_state[] |
| * [[VUID-vkCmdSetVertexInputEXT-None-08547]] |
| The <<features-shaderObject, pname:shaderObject>> feature must: be |
| enabled |
| endif::VK_EXT_vertex_input_dynamic_state[] |
| endif::VK_EXT_shader_object[] |
| ifndef::VK_EXT_shader_object[] |
| * [[VUID-vkCmdSetVertexInputEXT-None-04790]] |
| The <<features-vertexInputDynamicState, pname:vertexInputDynamicState>> |
| feature must: be enabled |
| endif::VK_EXT_shader_object[] |
| * [[VUID-vkCmdSetVertexInputEXT-vertexBindingDescriptionCount-04791]] |
| pname:vertexBindingDescriptionCount must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-vkCmdSetVertexInputEXT-vertexAttributeDescriptionCount-04792]] |
| pname:vertexAttributeDescriptionCount must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputAttributes |
| * [[VUID-vkCmdSetVertexInputEXT-binding-04793]] |
| For every pname:binding specified by each element of |
| pname:pVertexAttributeDescriptions, a |
| sname:VkVertexInputBindingDescription2EXT must: exist in |
| pname:pVertexBindingDescriptions with the same value of pname:binding |
| * [[VUID-vkCmdSetVertexInputEXT-pVertexBindingDescriptions-04794]] |
| All elements of pname:pVertexBindingDescriptions must: describe distinct |
| binding numbers |
| * [[VUID-vkCmdSetVertexInputEXT-pVertexAttributeDescriptions-04795]] |
| All elements of pname:pVertexAttributeDescriptions must: describe |
| distinct attribute locations |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetVertexInputEXT.adoc[] |
| -- |
| |
| [open,refpage='VkVertexInputBindingDescription2EXT',desc='Structure specifying the extended vertex input binding description',type='structs'] |
| -- |
| The sname:VkVertexInputBindingDescription2EXT structure is defined as: |
| |
| include::{generated}/api/structs/VkVertexInputBindingDescription2EXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:binding is the binding number that this structure describes. |
| * pname:stride is the byte stride between consecutive elements within the |
| buffer. |
| * pname:inputRate is a elink:VkVertexInputRate value specifying whether |
| vertex attribute addressing is a function of the vertex index or of the |
| instance index. |
| ifdef::VK_EXT_vertex_attribute_divisor[] |
| * pname:divisor is the number of successive instances that will use the |
| same value of the vertex attribute when instanced rendering is enabled. |
| This member can: be set to a value other than `1` if the |
| <<features-vertexAttributeInstanceRateDivisor, |
| pname:vertexAttributeInstanceRateDivisor>> feature is enabled. |
| For example, if the divisor is N, the same vertex attribute will be |
| applied to N successive instances before moving on to the next vertex |
| attribute. |
| The maximum value of pname:divisor is implementation-dependent and can |
| be queried using |
| sname:VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT::pname:maxVertexAttribDivisor. |
| A value of `0` can: be used for the divisor if the |
| <<features-vertexAttributeInstanceRateZeroDivisor, |
| pname:vertexAttributeInstanceRateZeroDivisor>> feature is enabled. |
| In this case, the same vertex attribute will be applied to all |
| instances. |
| endif::VK_EXT_vertex_attribute_divisor[] |
| ifndef::VK_EXT_vertex_attribute_divisor[] |
| * pname:divisor must: be set to `1` |
| endif::VK_EXT_vertex_attribute_divisor[] |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkVertexInputBindingDescription2EXT-binding-04796]] |
| pname:binding must: be less than |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-VkVertexInputBindingDescription2EXT-stride-04797]] |
| pname:stride must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindingStride |
| * [[VUID-VkVertexInputBindingDescription2EXT-divisor-04798]] |
| If the <<features-vertexAttributeInstanceRateZeroDivisor, |
| pname:vertexAttributeInstanceRateZeroDivisor>> feature is not enabled, |
| pname:divisor must: not be `0` |
| * [[VUID-VkVertexInputBindingDescription2EXT-divisor-04799]] |
| If the <<features-vertexAttributeInstanceRateDivisor, |
| pname:vertexAttributeInstanceRateDivisor>> feature is not enabled, |
| pname:divisor must: be `1` |
| * [[VUID-VkVertexInputBindingDescription2EXT-divisor-06226]] |
| pname:divisor must: be a value between `0` and |
| sname:VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT::pname:maxVertexAttribDivisor, |
| inclusive |
| * [[VUID-VkVertexInputBindingDescription2EXT-divisor-06227]] |
| If pname:divisor is not `1` then pname:inputRate must: be of type |
| ename:VK_VERTEX_INPUT_RATE_INSTANCE |
| **** |
| |
| include::{generated}/validity/structs/VkVertexInputBindingDescription2EXT.adoc[] |
| -- |
| |
| [open,refpage='VkVertexInputAttributeDescription2EXT',desc='Structure specifying the extended vertex input attribute description',type='structs'] |
| -- |
| The sname:VkVertexInputAttributeDescription2EXT structure is defined as: |
| |
| include::{generated}/api/structs/VkVertexInputAttributeDescription2EXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:location is the shader input location number for this attribute. |
| * pname:binding is the binding number which this attribute takes its data |
| from. |
| * pname:format is the size and type of the vertex attribute data. |
| * pname:offset is a byte offset of this attribute relative to the start of |
| an element in the vertex input binding. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkVertexInputAttributeDescription2EXT-location-06228]] |
| pname:location must: be less than |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputAttributes |
| * [[VUID-VkVertexInputAttributeDescription2EXT-binding-06229]] |
| pname:binding must: be less than |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-VkVertexInputAttributeDescription2EXT-offset-06230]] |
| pname:offset must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputAttributeOffset |
| * [[VUID-VkVertexInputAttributeDescription2EXT-format-04805]] |
| The <<resources-buffer-view-format-features,format features>> of |
| pname:format must: contain ename:VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
| ifdef::VK_KHR_portability_subset[] |
| * [[VUID-VkVertexInputAttributeDescription2EXT-vertexAttributeAccessBeyondStride-04806]] |
| If the `apiext:VK_KHR_portability_subset` extension is enabled, and |
| slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:vertexAttributeAccessBeyondStride |
| is ename:VK_FALSE, the sum of pname:offset plus the size of the vertex |
| attribute data described by pname:format must: not be greater than |
| pname:stride in the slink:VkVertexInputBindingDescription2EXT referenced |
| in pname:binding |
| endif::VK_KHR_portability_subset[] |
| **** |
| |
| include::{generated}/validity/structs/VkVertexInputAttributeDescription2EXT.adoc[] |
| -- |
| endif::VK_EXT_vertex_input_dynamic_state,VK_EXT_shader_object[] |
| |
| [open,refpage='vkCmdBindVertexBuffers',desc='Bind vertex buffers to a command buffer',type='protos'] |
| -- |
| To bind vertex buffers to a command buffer for use in subsequent drawing |
| commands, call: |
| |
| include::{generated}/api/protos/vkCmdBindVertexBuffers.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:firstBinding is the index of the first vertex input binding whose |
| state is updated by the command. |
| * pname:bindingCount is the number of vertex input bindings whose state is |
| updated by the command. |
| * pname:pBuffers is a pointer to an array of buffer handles. |
| * pname:pOffsets is a pointer to an array of buffer offsets. |
| |
| The values taken from elements [eq]#i# of pname:pBuffers and pname:pOffsets |
| replace the current state for the vertex input binding |
| [eq]#pname:firstBinding {plus} i#, for [eq]#i# in [eq]#[0, |
| pname:bindingCount)#. |
| The vertex input binding is updated to start at the offset indicated by |
| pname:pOffsets[i] from the start of the buffer pname:pBuffers[i]. |
| All vertex input attributes that use each of these bindings will use these |
| updated addresses in their address calculations for subsequent drawing |
| commands. |
| ifdef::VK_EXT_robustness2[] |
| If the <<features-nullDescriptor, pname:nullDescriptor>> feature is enabled, |
| elements of pname:pBuffers can: be dlink:VK_NULL_HANDLE, and can: be used by |
| the vertex shader. |
| If a vertex input attribute is bound to a vertex input binding that is |
| dlink:VK_NULL_HANDLE, the values taken from memory are considered to be |
| zero, and missing G, B, or A components are |
| <<fxvertex-input-extraction,filled with [eq]#(0,0,1)#>>. |
| endif::VK_EXT_robustness2[] |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdBindVertexBuffers-firstBinding-00624]] |
| pname:firstBinding must: be less than |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-vkCmdBindVertexBuffers-firstBinding-00625]] |
| The sum of pname:firstBinding and pname:bindingCount must: be less than |
| or equal to sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-vkCmdBindVertexBuffers-pOffsets-00626]] |
| All elements of pname:pOffsets must: be less than the size of the |
| corresponding element in pname:pBuffers |
| * [[VUID-vkCmdBindVertexBuffers-pBuffers-00627]] |
| All elements of pname:pBuffers must: have been created with the |
| ename:VK_BUFFER_USAGE_VERTEX_BUFFER_BIT flag |
| * [[VUID-vkCmdBindVertexBuffers-pBuffers-00628]] |
| Each element of pname:pBuffers that is non-sparse must: be bound |
| completely and contiguously to a single sname:VkDeviceMemory object |
| * [[VUID-vkCmdBindVertexBuffers-pBuffers-04001]] |
| If the <<features-nullDescriptor, pname:nullDescriptor>> feature is not |
| enabled, all elements of pname:pBuffers must: not be |
| dlink:VK_NULL_HANDLE |
| ifdef::VK_EXT_robustness2[] |
| * [[VUID-vkCmdBindVertexBuffers-pBuffers-04002]] |
| If an element of pname:pBuffers is dlink:VK_NULL_HANDLE, then the |
| corresponding element of pname:pOffsets must: be zero |
| endif::VK_EXT_robustness2[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdBindVertexBuffers.adoc[] |
| -- |
| |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| [open,refpage='vkCmdBindVertexBuffers2',desc='Bind vertex buffers to a command buffer and dynamically set strides',type='protos',alias='vkCmdBindVertexBuffers2EXT'] |
| -- |
| Alternatively, to bind vertex buffers, along with their sizes and strides, |
| to a command buffer for use in subsequent drawing commands, call: |
| |
| ifdef::VK_VERSION_1_3[] |
| include::{generated}/api/protos/vkCmdBindVertexBuffers2.adoc[] |
| |
| ifdef::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[or the equivalent command] |
| endif::VK_VERSION_1_3[] |
| |
| ifdef::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| include::{generated}/api/protos/vkCmdBindVertexBuffers2EXT.adoc[] |
| endif::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:firstBinding is the index of the first vertex input binding whose |
| state is updated by the command. |
| * pname:bindingCount is the number of vertex input bindings whose state is |
| updated by the command. |
| * pname:pBuffers is a pointer to an array of buffer handles. |
| * pname:pOffsets is a pointer to an array of buffer offsets. |
| * pname:pSizes is `NULL` or a pointer to an array of the size in bytes of |
| vertex data bound from pname:pBuffers. |
| * pname:pStrides is `NULL` or a pointer to an array of buffer strides. |
| |
| The values taken from elements [eq]#i# of pname:pBuffers and pname:pOffsets |
| replace the current state for the vertex input binding |
| [eq]#pname:firstBinding {plus} i#, for [eq]#i# in [eq]#[0, |
| pname:bindingCount)#. |
| The vertex input binding is updated to start at the offset indicated by |
| pname:pOffsets[i] from the start of the buffer pname:pBuffers[i]. |
| If pname:pSizes is not `NULL` then pname:pSizes[i] specifies the bound size |
| of the vertex buffer starting from the corresponding elements of |
| pname:pBuffers[i] plus pname:pOffsets[i]. |
| ifdef::VK_KHR_maintenance5[] |
| If pname:pSizes[i] is ename:VK_WHOLE_SIZE then the bound size is from |
| pname:pBuffers[i] plus pname:pOffsets[i] to the end of the buffer |
| pname:pBuffers[i]. |
| endif::VK_KHR_maintenance5[] |
| All vertex input attributes that use each of these bindings will use these |
| updated addresses in their address calculations for subsequent drawing |
| commands. |
| ifdef::VK_EXT_robustness2[] |
| If the <<features-nullDescriptor, pname:nullDescriptor>> feature is enabled, |
| elements of pname:pBuffers can: be dlink:VK_NULL_HANDLE, and can: be used by |
| the vertex shader. |
| If a vertex input attribute is bound to a vertex input binding that is |
| dlink:VK_NULL_HANDLE, the values taken from memory are considered to be |
| zero, and missing G, B, or A components are |
| <<fxvertex-input-extraction,filled with [eq]#(0,0,1)#>>. |
| endif::VK_EXT_robustness2[] |
| |
| This command also <<pipelines-dynamic-state, dynamically sets>> the byte |
| strides between consecutive elements within buffer pname:pBuffers[i] to the |
| corresponding pname:pStrides[i] value |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| Otherwise, strides are specified by the |
| sname:VkVertexInputBindingDescription::pname:stride values used to create |
| the currently active pipeline. |
| |
| ifdef::VK_EXT_vertex_input_dynamic_state,VK_EXT_shader_object[] |
| If |
| ifdef::VK_EXT_shader_object[drawing using <<shaders-objects, shader objects>>] |
| ifdef::VK_EXT_vertex_input_dynamic_state[] |
| ifdef::VK_EXT_shader_object[or if] |
| the bound pipeline state object was also created with the |
| ename:VK_DYNAMIC_STATE_VERTEX_INPUT_EXT dynamic state enabled |
| endif::VK_EXT_vertex_input_dynamic_state[] |
| then flink:vkCmdSetVertexInputEXT can: be used instead of |
| fname:vkCmdBindVertexBuffers2 to set the stride. |
| endif::VK_EXT_vertex_input_dynamic_state,VK_EXT_shader_object[] |
| |
| [NOTE] |
| .Note |
| ==== |
| Unlike the static state to set the same, pname:pStrides must be between 0 |
| and the maximum extent of the attributes in the binding. |
| ifdef::VK_EXT_vertex_input_dynamic_state,VK_EXT_shader_object[] |
| flink:vkCmdSetVertexInputEXT does not have this restriction so can be used |
| if other stride values are desired. |
| endif::VK_EXT_vertex_input_dynamic_state,VK_EXT_shader_object[] |
| ==== |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdBindVertexBuffers2-firstBinding-03355]] |
| pname:firstBinding must: be less than |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-vkCmdBindVertexBuffers2-firstBinding-03356]] |
| The sum of pname:firstBinding and pname:bindingCount must: be less than |
| or equal to sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-vkCmdBindVertexBuffers2-pOffsets-03357]] |
| If pname:pSizes is not `NULL`, all elements of pname:pOffsets must: be |
| less than the size of the corresponding element in pname:pBuffers |
| * [[VUID-vkCmdBindVertexBuffers2-pSizes-03358]] |
| If pname:pSizes is not `NULL`, all elements of pname:pOffsets plus |
| pname:pSizes |
| ifdef::VK_KHR_maintenance5[] |
| , where pname:pSizes is not ename:VK_WHOLE_SIZE, |
| endif::VK_KHR_maintenance5[] |
| must: be less than or equal to the size of the corresponding element in |
| pname:pBuffers |
| * [[VUID-vkCmdBindVertexBuffers2-pBuffers-03359]] |
| All elements of pname:pBuffers must: have been created with the |
| ename:VK_BUFFER_USAGE_VERTEX_BUFFER_BIT flag |
| * [[VUID-vkCmdBindVertexBuffers2-pBuffers-03360]] |
| Each element of pname:pBuffers that is non-sparse must: be bound |
| completely and contiguously to a single sname:VkDeviceMemory object |
| * [[VUID-vkCmdBindVertexBuffers2-pBuffers-04111]] |
| If the <<features-nullDescriptor, pname:nullDescriptor>> feature is not |
| enabled, all elements of pname:pBuffers must: not be |
| dlink:VK_NULL_HANDLE |
| ifdef::VK_EXT_robustness2[] |
| * [[VUID-vkCmdBindVertexBuffers2-pBuffers-04112]] |
| If an element of pname:pBuffers is dlink:VK_NULL_HANDLE, then the |
| corresponding element of pname:pOffsets must: be zero |
| endif::VK_EXT_robustness2[] |
| * [[VUID-vkCmdBindVertexBuffers2-pStrides-03362]] |
| If pname:pStrides is not `NULL` each element of pname:pStrides must: be |
| less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindingStride |
| * [[VUID-vkCmdBindVertexBuffers2-pStrides-06209]] |
| If pname:pStrides is not `NULL` each element of pname:pStrides must: be |
| either 0 or greater than or equal to the maximum extent of all vertex |
| input attributes fetched from the corresponding binding, where the |
| extent is calculated as the |
| slink:VkVertexInputAttributeDescription::pname:offset plus |
| slink:VkVertexInputAttributeDescription::pname:format size |
| **** |
| |
| include::{generated}/validity/protos/vkCmdBindVertexBuffers2.adoc[] |
| -- |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| |
| ifdef::VK_EXT_vertex_attribute_divisor[] |
| [[fxvertex-attribute_divisor]] |
| == Vertex Attribute Divisor in Instanced Rendering |
| |
| [open,refpage='VkPipelineVertexInputDivisorStateCreateInfoEXT',desc='Structure specifying vertex attributes assignment during instanced rendering',type='structs'] |
| -- |
| If the <<features-vertexAttributeInstanceRateDivisor, |
| pname:vertexAttributeInstanceRateDivisor>> feature is enabled and the |
| pname:pNext chain of slink:VkPipelineVertexInputStateCreateInfo includes a |
| sname:VkPipelineVertexInputDivisorStateCreateInfoEXT structure, then that |
| structure controls how vertex attributes are assigned to an instance when |
| instanced rendering is enabled. |
| |
| The sname:VkPipelineVertexInputDivisorStateCreateInfoEXT structure is |
| defined as: |
| |
| include::{generated}/api/structs/VkPipelineVertexInputDivisorStateCreateInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:vertexBindingDivisorCount is the number of elements in the |
| pname:pVertexBindingDivisors array. |
| * pname:pVertexBindingDivisors is a pointer to an array of |
| sname:VkVertexInputBindingDivisorDescriptionEXT structures specifying |
| the divisor value for each binding. |
| |
| include::{generated}/validity/structs/VkPipelineVertexInputDivisorStateCreateInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkVertexInputBindingDivisorDescriptionEXT',desc='Structure specifying a divisor used in instanced rendering',type='structs'] |
| -- |
| The individual divisor values per binding are specified using the |
| sname:VkVertexInputBindingDivisorDescriptionEXT structure which is defined |
| as: |
| |
| include::{generated}/api/structs/VkVertexInputBindingDivisorDescriptionEXT.adoc[] |
| |
| * pname:binding is the binding number for which the divisor is specified. |
| * pname:divisor is the number of successive instances that will use the |
| same value of the vertex attribute when instanced rendering is enabled. |
| For example, if the divisor is N, the same vertex attribute will be |
| applied to N successive instances before moving on to the next vertex |
| attribute. |
| The maximum value of pname:divisor is implementation-dependent and can |
| be queried using |
| sname:VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT::pname:maxVertexAttribDivisor. |
| A value of `0` can: be used for the divisor if the |
| <<features-vertexAttributeInstanceRateZeroDivisor, |
| pname:vertexAttributeInstanceRateZeroDivisor>> feature is enabled. |
| In this case, the same vertex attribute will be applied to all |
| instances. |
| |
| If this structure is not used to define a divisor value for an attribute, |
| then the divisor has a logical default value of 1. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkVertexInputBindingDivisorDescriptionEXT-binding-01869]] |
| pname:binding must: be less than |
| sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings |
| * [[VUID-VkVertexInputBindingDivisorDescriptionEXT-vertexAttributeInstanceRateZeroDivisor-02228]] |
| If the pname:vertexAttributeInstanceRateZeroDivisor feature is not |
| enabled, pname:divisor must: not be `0` |
| * [[VUID-VkVertexInputBindingDivisorDescriptionEXT-vertexAttributeInstanceRateDivisor-02229]] |
| If the pname:vertexAttributeInstanceRateDivisor feature is not enabled, |
| pname:divisor must: be `1` |
| * [[VUID-VkVertexInputBindingDivisorDescriptionEXT-divisor-01870]] |
| pname:divisor must: be a value between `0` and |
| sname:VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT::pname:maxVertexAttribDivisor, |
| inclusive |
| * [[VUID-VkVertexInputBindingDivisorDescriptionEXT-inputRate-01871]] |
| slink:VkVertexInputBindingDescription::pname:inputRate must: be of type |
| ename:VK_VERTEX_INPUT_RATE_INSTANCE for this pname:binding |
| **** |
| |
| include::{generated}/validity/structs/VkVertexInputBindingDivisorDescriptionEXT.adoc[] |
| -- |
| endif::VK_EXT_vertex_attribute_divisor[] |
| |
| |
| [[fxvertex-input-address-calculation]] |
| == Vertex Input Address Calculation |
| The address of each attribute for each code:vertexIndex and |
| code:instanceIndex is calculated as follows: |
| |
| * Let code:attribDesc be the member of |
| slink:VkPipelineVertexInputStateCreateInfo::pname:pVertexAttributeDescriptions |
| with sname:VkVertexInputAttributeDescription::pname:location equal to |
| the vertex input attribute number. |
| * Let code:bindingDesc be the member of |
| slink:VkPipelineVertexInputStateCreateInfo::pname:pVertexBindingDescriptions |
| with sname:VkVertexInputAttributeDescription::pname:binding equal to |
| code:attribDesc.binding. |
| * Let code:vertexIndex be the index of the vertex within the draw (a value |
| between pname:firstVertex and pname:firstVertex+pname:vertexCount for |
| fname:vkCmdDraw, or a value taken from the index buffer plus |
| pname:vertexOffset for fname:vkCmdDrawIndexed), and let |
| code:instanceIndex be the instance number of the draw (a value between |
| pname:firstInstance and pname:firstInstance+pname:instanceCount). |
| * Let code:offset be an array of offsets into the currently bound vertex |
| buffers specified during fname:vkCmdBindVertexBuffers |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[or fname:vkCmdBindVertexBuffers2] |
| with pname:pOffsets. |
| ifdef::VK_EXT_vertex_attribute_divisor[] |
| * Let code:divisor be the member of |
| slink:VkPipelineVertexInputDivisorStateCreateInfoEXT::pname:pVertexBindingDivisors |
| with sname:VkVertexInputBindingDivisorDescriptionEXT::pname:binding |
| equal to code:attribDesc.binding. |
| endif::VK_EXT_vertex_attribute_divisor[] |
| |
| [source,c] |
| ---- |
| bufferBindingAddress = buffer[binding].baseAddress + offset[binding]; |
| |
| if (bindingDesc.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) |
| effectiveVertexOffset = vertexIndex * bindingDesc.stride; |
| else |
| ifndef::VK_EXT_vertex_attribute_divisor[] |
| effectiveVertexOffset = instanceIndex * bindingDesc.stride; |
| endif::VK_EXT_vertex_attribute_divisor[] |
| ifdef::VK_EXT_vertex_attribute_divisor[] |
| if (divisor == 0) |
| effectiveVertexOffset = firstInstance * bindingDesc.stride; |
| else |
| effectiveVertexOffset = (firstInstance + ((instanceIndex - firstInstance) / divisor)) * bindingDesc.stride; |
| endif::VK_EXT_vertex_attribute_divisor[] |
| |
| attribAddress = bufferBindingAddress + effectiveVertexOffset + attribDesc.offset; |
| ---- |
| |
| |
| [[fxvertex-input-extraction]] |
| === Vertex Input Extraction |
| |
| For each attribute, raw data is extracted starting at `attribAddress` and is |
| converted from the sname:VkVertexInputAttributeDescription's pname:format to |
| either floating-point, unsigned integer, or signed integer based on the |
| <<formats-numericformat, numeric type>> of pname:format. |
| The numeric type of pname:format must: match the numeric type of the input |
| variable in the shader. |
| The input variable in the shader must: be declared as a 64-bit data type if |
| and only if pname:format is a 64-bit data type. |
| If pname:format is a packed format, `attribAddress` must: be a multiple of |
| the size in bytes of the whole attribute data type as described in |
| <<formats-packed,Packed Formats>>. |
| Otherwise, `attribAddress` must: be a multiple of the size in bytes of the |
| component type indicated by pname:format (see <<formats,Formats>>). |
| For attributes that are not 64-bit data types, each component is converted |
| to the format of the input variable based on its type and size (as defined |
| in the <<formats-definition,Format Definition>> section for each |
| elink:VkFormat), using the appropriate equations in <<fundamentals-fp16, |
| 16-Bit Floating-Point Numbers>>, <<fundamentals-fp11,Unsigned 11-Bit |
| Floating-Point Numbers>>, <<fundamentals-fp10,Unsigned 10-Bit Floating-Point |
| Numbers>>, <<fundamentals-fixedconv,Fixed-Point Data Conversion>>, and |
| <<textures-sexp-RGB,Shared Exponent to RGB>>. |
| Signed integer components smaller than 32 bits are sign-extended. |
| Attributes that are not 64-bit data types are expanded to four components in |
| the same way as described in <<textures-conversion-to-rgba,conversion to |
| RGBA>>. |
| The number of components in the vertex shader input variable need not |
| exactly match the number of components in the format. |
| If the vertex shader has fewer components, the extra components are |
| discarded. |