| // Copyright 2015-2023 The Khronos Group Inc. |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| [[drawing]] |
| = Drawing Commands |
| |
| _Drawing commands_ (commands with ftext:Draw in the name) provoke work in a |
| graphics pipeline. |
| Drawing commands are recorded into a command buffer and when executed by a |
| queue, will produce work which executes according to the bound graphics |
| ifndef::VK_EXT_shader_object[pipeline.] |
| ifdef::VK_EXT_shader_object[] |
| pipeline, or if the <<features-shaderObject, pname:shaderObject>> feature is |
| enabled, any <<shaders-objects, shader objects>> bound to graphics stages. |
| endif::VK_EXT_shader_object[] |
| A graphics pipeline |
| ifdef::VK_EXT_shader_object[] |
| or a combination of one or more graphics shader objects |
| endif::VK_EXT_shader_object[] |
| must: be bound to a command buffer before any drawing commands are recorded |
| in that command buffer. |
| |
| [open,refpage='VkPipelineInputAssemblyStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline input assembly state',type='structs'] |
| -- |
| ifdef::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| Drawing can be achieved in two modes: |
| |
| * <<drawing-mesh-shading,Programmable Mesh Shading>>, the mesh shader |
| assembles primitives, or |
| * <<drawing-primitive-shading,Programmable Primitive Shading>>, the input |
| primitives are assembled as follows. |
| |
| endif::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| |
| Each draw is made up of zero or more vertices and zero or more instances, |
| which are processed by the device and result in the assembly of primitives. |
| Primitives are assembled according to the pname:pInputAssemblyState member |
| of the slink:VkGraphicsPipelineCreateInfo structure, which is of type |
| sname:VkPipelineInputAssemblyStateCreateInfo: |
| |
| include::{generated}/api/structs/VkPipelineInputAssemblyStateCreateInfo.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:topology is a elink:VkPrimitiveTopology defining the primitive |
| topology, as described below. |
| * pname:primitiveRestartEnable controls whether a special vertex index |
| value is treated as restarting the assembly of primitives. |
| This enable only applies to indexed draws (flink:vkCmdDrawIndexed, |
| ifdef::VK_EXT_multi_draw[] |
| flink:vkCmdDrawMultiIndexedEXT, |
| endif::VK_EXT_multi_draw[] |
| and flink:vkCmdDrawIndexedIndirect), and the special index value is |
| either 0xFFFFFFFF when the pname:indexType parameter of |
| ifdef::VK_KHR_maintenance5[fname:vkCmdBindIndexBuffer2KHR or] |
| fname:vkCmdBindIndexBuffer is equal to ename:VK_INDEX_TYPE_UINT32, |
| ifdef::VK_EXT_index_type_uint8[] |
| 0xFF when pname:indexType is equal to ename:VK_INDEX_TYPE_UINT8_EXT, |
| endif::VK_EXT_index_type_uint8[] |
| or 0xFFFF when pname:indexType is equal to ename:VK_INDEX_TYPE_UINT16. |
| ifndef::VK_EXT_primitive_topology_list_restart[] |
| Primitive restart is not allowed for "`list`" topologies. |
| endif::VK_EXT_primitive_topology_list_restart[] |
| ifdef::VK_EXT_primitive_topology_list_restart[] |
| Primitive restart is not allowed for "`list`" topologies, unless one of |
| the features <<features-primitiveTopologyPatchListRestart, |
| pname:primitiveTopologyPatchListRestart>> (for |
| ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) or |
| <<features-primitiveTopologyListRestart, |
| pname:primitiveTopologyListRestart>> (for all other list topologies) is |
| enabled. |
| endif::VK_EXT_primitive_topology_list_restart[] |
| |
| Restarting the assembly of primitives discards the most recent index values |
| if those elements formed an incomplete primitive, and restarts the primitive |
| assembly using the subsequent indices, but only assembling the immediately |
| following element through the end of the originally specified elements. |
| The primitive restart index value comparison is performed before adding the |
| pname:vertexOffset value to the index value. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineInputAssemblyStateCreateInfo-topology-06252]] |
| If |
| ifdef::VK_EXT_primitive_topology_list_restart[] |
| the <<features-primitiveTopologyListRestart, |
| pname:primitiveTopologyListRestart>> feature is not enabled, and |
| endif::VK_EXT_primitive_topology_list_restart[] |
| pname:topology is ename:VK_PRIMITIVE_TOPOLOGY_POINT_LIST, |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST, |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, or |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, |
| pname:primitiveRestartEnable must: be ename:VK_FALSE |
| * [[VUID-VkPipelineInputAssemblyStateCreateInfo-topology-06253]] |
| If |
| ifdef::VK_EXT_primitive_topology_list_restart[] |
| the <<features-primitiveTopologyPatchListRestart, |
| pname:primitiveTopologyPatchListRestart>> feature is not enabled, and |
| endif::VK_EXT_primitive_topology_list_restart[] |
| pname:topology is ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, |
| pname:primitiveRestartEnable must: be ename:VK_FALSE |
| * [[VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00429]] |
| If the <<features-geometryShader, pname:geometryShader>> feature is not |
| enabled, pname:topology must: not be any of |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY |
| * [[VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00430]] |
| If the <<features-tessellationShader, pname:tessellationShader>> feature |
| is not enabled, pname:topology must: not be |
| ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST |
| ifdef::VK_KHR_portability_subset[] |
| * [[VUID-VkPipelineInputAssemblyStateCreateInfo-triangleFans-04452]] |
| If the `apiext:VK_KHR_portability_subset` extension is enabled, and |
| slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:triangleFans |
| is ename:VK_FALSE, pname:topology must: not be |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN |
| endif::VK_KHR_portability_subset[] |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineInputAssemblyStateCreateInfo.adoc[] |
| -- |
| |
| [open,refpage='VkPipelineInputAssemblyStateCreateFlags',desc='Reserved for future use',type='flags'] |
| -- |
| include::{generated}/api/flags/VkPipelineInputAssemblyStateCreateFlags.adoc[] |
| |
| tname:VkPipelineInputAssemblyStateCreateFlags is a bitmask type for setting |
| a mask, but is currently reserved for future use. |
| -- |
| |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetPrimitiveRestartEnable',desc='Set primitive assembly restart state dynamically for a command buffer',type='protos',alias='vkCmdSetPrimitiveRestartEnableEXT'] |
| -- |
| To <<pipelines-dynamic-state, dynamically control>> whether a special vertex |
| index value is treated as restarting the assembly of primitives, call: |
| |
| ifdef::VK_VERSION_1_3[] |
| include::{generated}/api/protos/vkCmdSetPrimitiveRestartEnable.adoc[] |
| |
| ifdef::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[or the equivalent command] |
| endif::VK_VERSION_1_3[] |
| |
| ifdef::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| include::{generated}/api/protos/vkCmdSetPrimitiveRestartEnableEXT.adoc[] |
| endif::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:primitiveRestartEnable controls whether a special vertex index |
| value is treated as restarting the assembly of primitives. |
| It behaves in the same way as |
| sname:VkPipelineInputAssemblyStateCreateInfo::pname:primitiveRestartEnable |
| |
| This command sets the primitive restart enable for subsequent drawing |
| commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineInputAssemblyStateCreateInfo::pname:primitiveRestartEnable |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetPrimitiveRestartEnable |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state2_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetPrimitiveRestartEnable.adoc[] |
| -- |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| |
| |
| [[drawing-primitive-topologies]] |
| == Primitive Topologies |
| |
| _Primitive topology_ determines how consecutive vertices are organized into |
| primitives, and determines the type of primitive that is used at the |
| beginning of the graphics pipeline. |
| The effective topology for later stages of the pipeline is altered by |
| tessellation or geometry shading (if either is in use) and depends on the |
| execution modes of those shaders. |
| ifdef::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| In the case of mesh shading the only effective topology is defined by the |
| execution mode of the mesh shader. |
| endif::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| |
| [open,refpage='VkPrimitiveTopology',desc='Supported primitive topologies',type='enums'] |
| -- |
| The primitive topologies defined by elink:VkPrimitiveTopology are: |
| |
| include::{generated}/api/enums/VkPrimitiveTopology.adoc[] |
| |
| * ename:VK_PRIMITIVE_TOPOLOGY_POINT_LIST specifies a series of |
| <<drawing-point-lists,separate point primitives>>. |
| * ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST specifies a series of |
| <<drawing-line-lists,separate line primitives>>. |
| * ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP specifies a series of |
| <<drawing-line-strips,connected line primitives>> with consecutive lines |
| sharing a vertex. |
| * ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST specifies a series of |
| <<drawing-triangle-lists,separate triangle primitives>>. |
| * ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP specifies a series of |
| <<drawing-triangle-strips,connected triangle primitives>> with |
| consecutive triangles sharing an edge. |
| * ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN specifies a series of |
| <<drawing-triangle-fans,connected triangle primitives>> with all |
| triangles sharing a common vertex. |
| ifdef::VK_KHR_portability_subset[] |
| If the `apiext:VK_KHR_portability_subset` extension is enabled, and |
| slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:triangleFans |
| is ename:VK_FALSE, then triangle fans are not supported by the |
| implementation, and ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN must: not |
| be used. |
| endif::VK_KHR_portability_subset[] |
| * ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY specifies a series |
| of <<drawing-line-lists-with-adjacency,separate line primitives with |
| adjacency>>. |
| * ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY specifies a series |
| of <<drawing-line-strips-with-adjacency,connected line primitives with |
| adjacency>>, with consecutive primitives sharing three vertices. |
| * ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY specifies a |
| series of <<drawing-triangle-lists-with-adjacency,separate triangle |
| primitives with adjacency>>. |
| * ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY specifies |
| <<drawing-triangle-strips-with-adjacency,connected triangle primitives |
| with adjacency>>, with consecutive triangles sharing an edge. |
| * ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST specifies |
| <<drawing-patch-lists,separate patch primitives>>. |
| |
| Each primitive topology, and its construction from a list of vertices, is |
| described in detail below with a supporting diagram, according to the |
| following key: |
| |
| [cols="1,2,9"] |
| |==== |
| ^.^| image:{images}/primitive_topology_key_vertex.svg[pdfwidth=6pt,align="center",opts="{imageopts}"] |
| .^| Vertex |
| | A point in 3-dimensional space. |
| Positions chosen within the diagrams are arbitrary and for |
| illustration only. |
| |
| ^.^| image:{images}/primitive_topology_key_vertex_number.svg[pdfwidth=6pt,align="center",opts="{imageopts}"] |
| .^| Vertex Number |
| | Sequence position of a vertex within the provided vertex data. |
| |
| ^.^| image:{images}/primitive_topology_key_provoking_vertex.svg[pdfwidth=30pt,align="center",opts="{imageopts}"] |
| .^| Provoking Vertex |
| | Provoking vertex within the main primitive. |
| The tail is angled towards the relevant primitive. |
| Used in <<vertexpostproc-flatshading, flat shading>>. |
| |
| ^.^| image:{images}/primitive_topology_key_edge.svg[pdfwidth=30pt,align="center",opts="{imageopts}"] |
| .^| Primitive Edge |
| | An edge connecting the points of a main primitive. |
| |
| ^.^| image:{images}/primitive_topology_key_adjacency_edge.svg[pdfwidth=30pt,align="center",opts="{imageopts}"] |
| .^| Adjacency Edge |
| | Points connected by these lines do not contribute to a main primitive, |
| and are only accessible in a <<geometry,geometry shader>>. |
| |
| ^.^| image:{images}/primitive_topology_key_winding_order.svg[pdfwidth=30pt,align="center",opts="{imageopts}"] |
| .^| Winding Order |
| | The relative order in which vertices are defined within a primitive, |
| used in the <<primsrast-polygons-basic,facing determination>>. |
| This ordering has no specific start or end point. |
| |==== |
| |
| The diagrams are supported with mathematical definitions where the vertices |
| ([eq]#v#) and primitives ([eq]#p#) are numbered starting from [eq]#0#; |
| [eq]#v~0~# is the first vertex in the provided data and [eq]#p~0~# is the |
| first primitive in the set of primitives defined by the vertices and |
| topology. |
| -- |
| |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetPrimitiveTopology',desc='Set primitive topology state dynamically for a command buffer',type='protos',alias='vkCmdSetPrimitiveTopologyEXT'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> primitive topology, call: |
| |
| ifdef::VK_VERSION_1_3[] |
| include::{generated}/api/protos/vkCmdSetPrimitiveTopology.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/vkCmdSetPrimitiveTopologyEXT.adoc[] |
| endif::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:primitiveTopology specifies the primitive topology to use for |
| drawing. |
| |
| This command sets the primitive topology for subsequent drawing commands |
| 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_PRIMITIVE_TOPOLOGY set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineInputAssemblyStateCreateInfo::pname:topology value used to |
| create the currently active pipeline. |
| |
| :refpage: vkCmdSetPrimitiveTopology |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetPrimitiveTopology.adoc[] |
| -- |
| |
| |
| [[drawing-primitive-topology-class]] |
| === Topology Class |
| |
| The primitive topologies are grouped into the following topology classes: |
| |
| [[topology-classes]] |
| .Topology classes |
| [options="header"] |
| |=== |
| | Topology Class | Primitive Topology |
| | Point | ename:VK_PRIMITIVE_TOPOLOGY_POINT_LIST |
| | Line | ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST, |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY |
| | Triangle | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY |
| | Patch | ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST |
| |=== |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| |
| [[drawing-point-lists]] |
| === Point Lists |
| |
| When the topology is ename:VK_PRIMITIVE_TOPOLOGY_POINT_LIST, each |
| consecutive vertex defines a single point primitive, according to the |
| equation: |
| |
| {empty}:: [eq]#p~i~ = {v~i~}# |
| |
| As there is only one vertex, that vertex is the provoking vertex. |
| The number of primitives generated is equal to [eq]#pname:vertexCount#. |
| |
| image::{images}/primitive_topology_point_list.svg[align="center",opts="{imageopts}"] |
| |
| |
| [[drawing-line-lists]] |
| === Line Lists |
| |
| When the primitive topology is ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST, each |
| consecutive pair of vertices defines a single line primitive, according to |
| the equation: |
| |
| {empty}:: [eq]#p~i~ = {v~2i~, v~2i+1~}# |
| |
| The number of primitives generated is equal to |
| [eq]#{lfloor}pname:vertexCount/2{rfloor}#. |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the |
| endif::VK_EXT_provoking_vertex[] |
| ifndef::VK_EXT_provoking_vertex[] |
| The |
| endif::VK_EXT_provoking_vertex[] |
| provoking vertex for [eq]#p~i~# is [eq]#v~2i~#. |
| |
| image::{images}/primitive_topology_line_list.svg[align="center",opts="{imageopts}"] |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the provoking vertex for |
| [eq]#p~i~# is [eq]#v~2i+1~#. |
| |
| image::{images}/primitive_topology_line_list_last.svg[align="center",opts="{imageopts}"] |
| endif::VK_EXT_provoking_vertex[] |
| |
| |
| [[drawing-line-strips]] |
| === Line Strips |
| |
| When the primitive topology is ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, one |
| line primitive is defined by each vertex and the following vertex, according |
| to the equation: |
| |
| {empty}:: [eq]#p~i~ = {v~i~, v~i+1~}# |
| |
| The number of primitives generated is equal to |
| [eq]#max(0,pname:vertexCount-1)#. |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the |
| endif::VK_EXT_provoking_vertex[] |
| ifndef::VK_EXT_provoking_vertex[] |
| The |
| endif::VK_EXT_provoking_vertex[] |
| provoking vertex for [eq]#p~i~# is [eq]#v~i~#. |
| |
| image::{images}/primitive_topology_line_strip.svg[align="center",opts="{imageopts}"] |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the provoking vertex for |
| [eq]#p~i~# is [eq]#v~i+1~#. |
| |
| image::{images}/primitive_topology_line_strip_last.svg[align="center",opts="{imageopts}"] |
| endif::VK_EXT_provoking_vertex[] |
| |
| |
| [[drawing-triangle-lists]] |
| === Triangle Lists |
| |
| When the primitive topology is ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, |
| each consecutive set of three vertices defines a single triangle primitive, |
| according to the equation: |
| |
| {empty}:: [eq]#p~i~ = {v~3i~, v~3i+1~, v~3i+2~}# |
| |
| The number of primitives generated is equal to |
| [eq]#{lfloor}pname:vertexCount/3{rfloor}#. |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the |
| endif::VK_EXT_provoking_vertex[] |
| ifndef::VK_EXT_provoking_vertex[] |
| The |
| endif::VK_EXT_provoking_vertex[] |
| provoking vertex for [eq]#p~i~# is [eq]#v~3i~#. |
| |
| image::{images}/primitive_topology_triangle_list.svg[align="center",opts="{imageopts}"] |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the provoking vertex for |
| [eq]#p~i~# is [eq]#v~3i+2~#. |
| |
| image::{images}/primitive_topology_triangle_list_last.svg[align="center",opts="{imageopts}"] |
| endif::VK_EXT_provoking_vertex[] |
| |
| |
| [[drawing-triangle-strips]] |
| === Triangle Strips |
| |
| When the primitive topology is ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, |
| one triangle primitive is defined by each vertex and the two vertices that |
| follow it, according to the equation: |
| |
| {empty}:: [eq]#p~i~ = {v~i~, v~i+(1+i%2)~, v~i+(2-i%2)~}# |
| |
| The number of primitives generated is equal to |
| [eq]#max(0,pname:vertexCount-2)#. |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the |
| endif::VK_EXT_provoking_vertex[] |
| ifndef::VK_EXT_provoking_vertex[] |
| The |
| endif::VK_EXT_provoking_vertex[] |
| provoking vertex for [eq]#p~i~# is [eq]#v~i~#. |
| |
| image::{images}/primitive_topology_triangle_strip.svg[align="center",opts="{imageopts}"] |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the provoking vertex for |
| [eq]#p~i~# is [eq]#v~i+2~#. |
| |
| image::{images}/primitive_topology_triangle_strip_last.svg[align="center",opts="{imageopts}"] |
| endif::VK_EXT_provoking_vertex[] |
| |
| [NOTE] |
| .Note |
| ==== |
| The ordering of the vertices in each successive triangle is reversed, so |
| that the winding order is consistent throughout the strip. |
| ==== |
| |
| |
| [[drawing-triangle-fans]] |
| === Triangle Fans |
| |
| When the primitive topology is ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, |
| triangle primitives are defined around a shared common vertex, according to |
| the equation: |
| |
| {empty}:: [eq]#p~i~ = {v~i+1~, v~i+2~, v~0~}# |
| |
| The number of primitives generated is equal to |
| [eq]#max(0,pname:vertexCount-2)#. |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the |
| endif::VK_EXT_provoking_vertex[] |
| ifndef::VK_EXT_provoking_vertex[] |
| The |
| endif::VK_EXT_provoking_vertex[] |
| provoking vertex for [eq]#p~i~# is [eq]#v~i+1~#. |
| |
| image::{images}/primitive_topology_triangle_fan.svg[align="center",opts="{imageopts}"] |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the provoking vertex for |
| [eq]#p~i~# is [eq]#v~i+2~#. |
| |
| image::{images}/primitive_topology_triangle_fan_last.svg[align="center",opts="{imageopts}"] |
| endif::VK_EXT_provoking_vertex[] |
| |
| ifdef::VK_KHR_portability_subset[] |
| [NOTE] |
| .Note |
| ==== |
| If the `apiext:VK_KHR_portability_subset` extension is enabled, and |
| slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:triangleFans is |
| ename:VK_FALSE, then triangle fans are not supported by the implementation, |
| and ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN must: not be used. |
| ==== |
| endif::VK_KHR_portability_subset[] |
| |
| |
| [[drawing-line-lists-with-adjacency]] |
| === Line Lists With Adjacency |
| |
| When the primitive topology is |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, each consecutive set |
| of four vertices defines a single line primitive with adjacency, according |
| to the equation: |
| |
| {empty}:: [eq]#p~i~ = {v~4i~, v~4i+1~, v~4i+2~,v~4i+3~}# |
| |
| A line primitive is described by the second and third vertices of the total |
| primitive, with the remaining two vertices only accessible in a |
| <<geometry,geometry shader>>. |
| |
| The number of primitives generated is equal to |
| [eq]#{lfloor}pname:vertexCount/4{rfloor}#. |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the |
| endif::VK_EXT_provoking_vertex[] |
| ifndef::VK_EXT_provoking_vertex[] |
| The |
| endif::VK_EXT_provoking_vertex[] |
| provoking vertex for [eq]#p~i~# is [eq]#v~4i+1~#. |
| |
| image::{images}/primitive_topology_line_list_with_adjacency.svg[align="center",opts="{imageopts}"] |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the provoking vertex for |
| [eq]#p~i~# is [eq]#v~4i+2~#. |
| |
| image::{images}/primitive_topology_line_list_with_adjacency_last.svg[align="center",opts="{imageopts}"] |
| endif::VK_EXT_provoking_vertex[] |
| |
| |
| [[drawing-line-strips-with-adjacency]] |
| === Line Strips With Adjacency |
| |
| When the primitive topology is |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, one line primitive |
| with adjacency is defined by each vertex and the following vertex, according |
| to the equation: |
| |
| {empty}:: [eq]#p~i~ = {v~i~, v~i+1~, v~i+2~, v~i+3~}# |
| |
| A line primitive is described by the second and third vertices of the total |
| primitive, with the remaining two vertices only accessible in a |
| <<geometry,geometry shader>>. |
| |
| The number of primitives generated is equal to |
| [eq]#max(0,pname:vertexCount-3)#. |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the |
| endif::VK_EXT_provoking_vertex[] |
| ifndef::VK_EXT_provoking_vertex[] |
| The |
| endif::VK_EXT_provoking_vertex[] |
| provoking vertex for [eq]#p~i~# is [eq]#v~i+1~#. |
| |
| image::{images}/primitive_topology_line_strip_with_adjacency.svg[align="center",opts="{imageopts}"] |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the provoking vertex for |
| [eq]#p~i~# is [eq]#v~i+2~#. |
| |
| image::{images}/primitive_topology_line_strip_with_adjacency_last.svg[align="center",opts="{imageopts}"] |
| endif::VK_EXT_provoking_vertex[] |
| |
| |
| [[drawing-triangle-lists-with-adjacency]] |
| === Triangle Lists With Adjacency |
| |
| When the primitive topology is |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, each consecutive |
| set of six vertices defines a single triangle primitive with adjacency, |
| according to the equations: |
| |
| {empty}:: [eq]#p~i~ = {v~6i~, v~6i+1~, v~6i+2~, v~6i+3~, v~6i+4~, |
| v~6i+5~}# |
| |
| A triangle primitive is described by the first, third, and fifth vertices of |
| the total primitive, with the remaining three vertices only accessible in a |
| <<geometry,geometry shader>>. |
| |
| The number of primitives generated is equal to |
| [eq]#{lfloor}pname:vertexCount/6{rfloor}#. |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the |
| endif::VK_EXT_provoking_vertex[] |
| ifndef::VK_EXT_provoking_vertex[] |
| The |
| endif::VK_EXT_provoking_vertex[] |
| provoking vertex for [eq]#p~i~# is [eq]#v~6i~#. |
| |
| image::{images}/primitive_topology_triangle_list_with_adjacency.svg[align="center",opts="{imageopts}"] |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the provoking vertex for |
| [eq]#p~i~# is [eq]#v~6i+4~#. |
| |
| image::{images}/primitive_topology_triangle_list_with_adjacency_last.svg[align="center",opts="{imageopts}"] |
| endif::VK_EXT_provoking_vertex[] |
| |
| |
| [[drawing-triangle-strips-with-adjacency]] |
| === Triangle Strips With Adjacency |
| |
| When the primitive topology is |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, one triangle |
| primitive with adjacency is defined by each vertex and the following 5 |
| vertices. |
| |
| The number of primitives generated, [eq]#n#, is equal to [eq]#{lfloor}max(0, |
| pname:vertexCount - 4)/2{rfloor}#. |
| |
| If [eq]#n=1#, the primitive is defined as: |
| |
| {empty}:: [eq]#p = {v~0~, v~1~, v~2~, v~5~, v~4~, v~3~}# |
| |
| If [eq]#n>1#, the total primitive consists of different vertices according |
| to where it is in the strip: |
| |
| {empty}:: [eq]#p~i~ = {v~2i~, v~2i+1~, v~2i+2~, v~2i+6~, v~2i+4~, |
| v~2i+3~}# when [eq]#i=0# |
| {empty}:: [eq]#p~i~ = {v~2i~, v~2i+3~, v~2i+4~, v~2i+6~, v~2i+2~, |
| v~2i-2~}# when [eq]#i>0#, [eq]#i<n-1#, and [eq]#i%2=1# |
| {empty}:: [eq]#p~i~ = {v~2i~, v~2i-2~, v~2i+2~, v~2i+6~, v~2i+4~, |
| v~2i+3~}# when [eq]#i>0#, [eq]#i<n-1#, and [eq]#i%2=0# |
| {empty}:: [eq]#p~i~ = {v~2i~, v~2i+3~, v~2i+4~, v~2i+5~, v~2i+2~, |
| v~2i-2~}# when [eq]#i=n-1# and [eq]#i%2=1# |
| {empty}:: [eq]#p~i~ = {v~2i~, v~2i-2~, v~2i+2~, v~2i+5~, v~2i+4~, |
| v~2i+3~}# when [eq]#i=n-1# and [eq]#i%2=0# |
| |
| A triangle primitive is described by the first, third, and fifth vertices of |
| the total primitive in all cases, with the remaining three vertices only |
| accessible in a <<geometry,geometry shader>>. |
| |
| [NOTE] |
| .Note |
| ==== |
| The ordering of the vertices in each successive triangle is altered so that |
| the winding order is consistent throughout the strip. |
| ==== |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the |
| endif::VK_EXT_provoking_vertex[] |
| ifndef::VK_EXT_provoking_vertex[] |
| The |
| endif::VK_EXT_provoking_vertex[] |
| provoking vertex for [eq]#p~i~# is always [eq]#v~2i~#. |
| |
| image::{images}/primitive_topology_triangle_strip_with_adjacency.svg[align="center",opts="{imageopts}"] |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the provoking vertex for |
| [eq]#p~i~# is always [eq]#v~2i+4~#. |
| |
| image::{images}/primitive_topology_triangle_strip_with_adjacency_last.svg[align="center",opts="{imageopts}"] |
| endif::VK_EXT_provoking_vertex[] |
| |
| |
| [[drawing-patch-lists]] |
| === Patch Lists |
| |
| When the primitive topology is ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, each |
| consecutive set of [eq]#m# vertices defines a single patch primitive, |
| according to the equation: |
| |
| {empty}:: [eq]#p~i~ = {v~mi~, v~mi+1~, ..., v~mi+(m-2)~, v~mi+(m-1)~}# |
| |
| where [eq]#m# is equal to |
| slink:VkPipelineTessellationStateCreateInfo::pname:patchControlPoints. |
| |
| Patch lists are never passed to <<vertexpostproc, vertex post-processing>>, |
| and as such no provoking vertex is defined for patch primitives. |
| The number of primitives generated is equal to |
| [eq]#{lfloor}pname:vertexCount/m{rfloor}#. |
| |
| The vertices comprising a patch have no implied geometry, and are used as |
| inputs to tessellation shaders and the fixed-function tessellator to |
| generate new point, line, or triangle primitives. |
| |
| |
| [[drawing-primitive-order]] |
| == Primitive Order |
| |
| Primitives generated by <<drawing, drawing commands>> progress through the |
| stages of the <<synchronization-pipeline-graphics, graphics pipeline>> in |
| _primitive order_. |
| Primitive order is initially determined in the following way: |
| |
| . Submission order determines the initial ordering |
| . For indirect drawing commands, the order in which accessed instances of |
| the slink:VkDrawIndirectCommand are stored in pname:buffer, from lower |
| indirect buffer addresses to higher addresses. |
| . If a drawing command includes multiple instances, the order in which |
| instances are executed, from lower numbered instances to higher. |
| . The order in which primitives are specified by a drawing command: |
| ** For non-indexed draws, from vertices with a lower numbered |
| code:vertexIndex to a higher numbered code:vertexIndex. |
| ** For indexed draws, vertices sourced from a lower index buffer addresses |
| to higher addresses. |
| ifdef::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| ** For draws using mesh shaders, the order is provided by <<mesh-ordering, |
| mesh shading>>. |
| endif::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| ifdef::VK_HUAWEI_cluster_culling_shader[] |
| ** For draws using cluster culling shaders, the order is provided by |
| <<cluster-culling-cluster-ordering, cluster culling shading>>. |
| endif::VK_HUAWEI_cluster_culling_shader[] |
| |
| Within this order implementations further sort primitives: |
| |
| [start=5] |
| . If tessellation shading is active, by an implementation-dependent order |
| of new primitives generated by <<tessellation-primitive-order, |
| tessellation>>. |
| . If geometry shading is active, by the order new primitives are generated |
| by <<geometry-ordering, geometry shading>>. |
| . If the <<primsrast-polygonmode,polygon mode>> is not |
| ename:VK_POLYGON_MODE_FILL, |
| ifdef::VK_NV_fill_rectangle[] |
| or ename:VK_POLYGON_MODE_FILL_RECTANGLE_NV, |
| endif::VK_NV_fill_rectangle[] |
| by an implementation-dependent ordering of the new primitives generated |
| within the original primitive. |
| |
| Primitive order is later used to define <<primsrast-order, rasterization |
| order>>, which determines the order in which fragments output results to a |
| framebuffer. |
| |
| |
| [[drawing-primitive-shading]] |
| == Programmable Primitive Shading |
| |
| Once primitives are assembled, they proceed to the vertex shading stage of |
| the pipeline. |
| If the draw includes multiple instances, then the set of primitives is sent |
| to the vertex shading stage multiple times, once for each instance. |
| |
| It is implementation-dependent whether vertex shading occurs on vertices |
| that are discarded as part of incomplete primitives, but if it does occur |
| then it operates as if they were vertices in complete primitives and such |
| invocations can: have side effects. |
| |
| Vertex shading receives two per-vertex inputs from the primitive assembly |
| stage - the code:vertexIndex and the code:instanceIndex. |
| How these values are generated is defined below, with each command. |
| |
| Drawing commands fall roughly into two categories: |
| |
| * Non-indexed drawing commands present a sequential code:vertexIndex to |
| the vertex shader. |
| The sequential index is generated automatically by the device (see |
| <<fxvertex,Fixed-Function Vertex Processing>> for details on both |
| specifying the vertex attributes indexed by code:vertexIndex, as well as |
| binding vertex buffers containing those attributes to a command buffer). |
| These commands are: |
| ** flink:vkCmdDraw |
| ** flink:vkCmdDrawIndirect |
| ifdef::VK_VERSION_1_2[] |
| ** flink:vkCmdDrawIndirectCount |
| endif::VK_VERSION_1_2[] |
| ifdef::VK_KHR_draw_indirect_count[] |
| ** flink:vkCmdDrawIndirectCountKHR |
| endif::VK_KHR_draw_indirect_count[] |
| ifdef::VK_AMD_draw_indirect_count[] |
| ** flink:vkCmdDrawIndirectCountAMD |
| endif::VK_AMD_draw_indirect_count[] |
| ifdef::VK_EXT_multi_draw[] |
| ** flink:vkCmdDrawMultiEXT |
| endif::VK_EXT_multi_draw[] |
| * Indexed drawing commands read index values from an _index buffer_ and |
| use this to compute the code:vertexIndex value for the vertex shader. |
| These commands are: |
| ** flink:vkCmdDrawIndexed |
| ** flink:vkCmdDrawIndexedIndirect |
| ifdef::VK_VERSION_1_2[] |
| ** flink:vkCmdDrawIndexedIndirectCount |
| endif::VK_VERSION_1_2[] |
| ifdef::VK_KHR_draw_indirect_count[] |
| ** flink:vkCmdDrawIndexedIndirectCountKHR |
| endif::VK_KHR_draw_indirect_count[] |
| ifdef::VK_AMD_draw_indirect_count[] |
| ** flink:vkCmdDrawIndexedIndirectCountAMD |
| endif::VK_AMD_draw_indirect_count[] |
| ifdef::VK_EXT_multi_draw[] |
| ** flink:vkCmdDrawMultiIndexedEXT |
| endif::VK_EXT_multi_draw[] |
| |
| |
| [open,refpage='vkCmdBindIndexBuffer',desc='Bind an index buffer to a command buffer',type='protos'] |
| -- |
| :refpage: vkCmdBindIndexBuffer |
| |
| To bind an index buffer to a command buffer, call: |
| |
| include::{generated}/api/protos/vkCmdBindIndexBuffer.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:buffer is the buffer being bound. |
| * pname:offset is the starting offset in bytes within pname:buffer used in |
| index buffer address calculations. |
| * pname:indexType is a elink:VkIndexType value specifying the size of the |
| indices. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/bind_index_buffer_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdBindIndexBuffer.adoc[] |
| -- |
| |
| ifdef::VK_KHR_maintenance5[] |
| [open,refpage='vkCmdBindIndexBuffer2KHR',desc='Bind an index buffer to a command buffer',type='protos'] |
| -- |
| :refpage: vkCmdBindIndexBuffer2KHR |
| |
| To bind an index buffer, along with its size, to a command buffer, call: |
| |
| include::{generated}/api/protos/vkCmdBindIndexBuffer2KHR.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:buffer is the buffer being bound. |
| * pname:offset is the starting offset in bytes within pname:buffer used in |
| index buffer address calculations. |
| * pname:size is the size in bytes of index data bound from pname:buffer. |
| * pname:indexType is a elink:VkIndexType value specifying the size of the |
| indices. |
| |
| pname:size specifies the bound size of the index buffer starting from |
| pname:offset. |
| If pname:size is ename:VK_WHOLE_SIZE then the bound size is from |
| pname:offset to the end of the pname:buffer. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/bind_index_buffer_common.adoc[] |
| * [[VUID-vkCmdBindIndexBuffer2KHR-size-08767]] |
| If pname:size is not ename:VK_WHOLE_SIZE, pname:size must: be a multiple |
| of the size of the type indicated by pname:indexType |
| * [[VUID-vkCmdBindIndexBuffer2KHR-size-08768]] |
| If pname:size is not ename:VK_WHOLE_SIZE, the sum of pname:offset and |
| pname:size must: be less than or equal to the size of pname:buffer |
| **** |
| |
| include::{generated}/validity/protos/vkCmdBindIndexBuffer2KHR.adoc[] |
| -- |
| endif::VK_KHR_maintenance5[] |
| |
| [open,refpage='VkIndexType',desc='Type of index buffer indices',type='enums'] |
| -- |
| Possible values of |
| ifdef::VK_KHR_maintenance5[flink:vkCmdBindIndexBuffer2KHR::pname:indexType and] |
| flink:vkCmdBindIndexBuffer::pname:indexType, specifying the size of indices, |
| are: |
| |
| include::{generated}/api/enums/VkIndexType.adoc[] |
| |
| * ename:VK_INDEX_TYPE_UINT16 specifies that indices are 16-bit unsigned |
| integer values. |
| * ename:VK_INDEX_TYPE_UINT32 specifies that indices are 32-bit unsigned |
| integer values. |
| ifdef::VK_NV_ray_tracing,VK_KHR_acceleration_structure[] |
| * ename:VK_INDEX_TYPE_NONE_KHR specifies that no indices are provided. |
| endif::VK_NV_ray_tracing,VK_KHR_acceleration_structure[] |
| ifdef::VK_EXT_index_type_uint8[] |
| * ename:VK_INDEX_TYPE_UINT8_EXT specifies that indices are 8-bit unsigned |
| integer values. |
| endif::VK_EXT_index_type_uint8[] |
| -- |
| |
| The parameters for each drawing command are specified directly in the |
| command or read from buffer memory, depending on the command. |
| Drawing commands that source their parameters from buffer memory are known |
| as _indirect_ drawing commands. |
| |
| All drawing commands interact with the <<features-robustBufferAccess, |
| pname:robustBufferAccess>> feature. |
| |
| [open,refpage='vkCmdDraw',desc='Draw primitives',type='protos'] |
| -- |
| :refpage: vkCmdDraw |
| |
| To record a non-indexed draw, call: |
| |
| include::{generated}/api/protos/vkCmdDraw.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:vertexCount is the number of vertices to draw. |
| * pname:instanceCount is the number of instances to draw. |
| * pname:firstVertex is the index of the first vertex to draw. |
| * pname:firstInstance is the instance ID of the first instance to draw. |
| |
| When the command is executed, primitives are assembled using the current |
| primitive topology and pname:vertexCount consecutive vertex indices with the |
| first code:vertexIndex value equal to pname:firstVertex. |
| The primitives are drawn pname:instanceCount times with code:instanceIndex |
| starting with pname:firstInstance and increasing sequentially for each |
| instance. |
| The assembled primitives execute the bound graphics pipeline. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/draw_common.adoc[] |
| include::{chapters}/commonvalidity/draw_dispatch_nonindirect_common.adoc[] |
| include::{chapters}/commonvalidity/draw_vertex_binding.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdDraw.adoc[] |
| -- |
| |
| [open,refpage='vkCmdDrawIndexed',desc='Draw primitives with indexed vertices',type='protos'] |
| -- |
| :refpage: vkCmdDrawIndexed |
| |
| To record an indexed draw, call: |
| |
| include::{generated}/api/protos/vkCmdDrawIndexed.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:indexCount is the number of vertices to draw. |
| * pname:instanceCount is the number of instances to draw. |
| * pname:firstIndex is the base index within the index buffer. |
| * pname:vertexOffset is the value added to the vertex index before |
| indexing into the vertex buffer. |
| * pname:firstInstance is the instance ID of the first instance to draw. |
| |
| When the command is executed, primitives are assembled using the current |
| primitive topology and pname:indexCount vertices whose indices are retrieved |
| from the index buffer. |
| The index buffer is treated as an array of tightly packed unsigned integers |
| of size defined by the |
| ifdef::VK_KHR_maintenance5[flink:vkCmdBindIndexBuffer2KHR::pname:indexType or the] |
| flink:vkCmdBindIndexBuffer::pname:indexType parameter with which the buffer |
| was bound. |
| |
| The first vertex index is at an offset of [eq]#pname:firstIndex {times} |
| code:indexSize {plus} pname:offset# within the bound index buffer, where |
| pname:offset is the offset specified by fname:vkCmdBindIndexBuffer |
| ifdef::VK_KHR_maintenance5[or fname:vkCmdBindIndexBuffer2KHR,] |
| and code:indexSize is the byte size of the type specified by |
| pname:indexType. |
| Subsequent index values are retrieved from consecutive locations in the |
| index buffer. |
| Indices are first compared to the primitive restart value, then zero |
| extended to 32 bits (if the code:indexType is |
| ifdef::VK_EXT_index_type_uint8[] |
| ename:VK_INDEX_TYPE_UINT8_EXT or |
| endif::VK_EXT_index_type_uint8[] |
| ename:VK_INDEX_TYPE_UINT16) and have pname:vertexOffset added to them, |
| before being supplied as the code:vertexIndex value. |
| |
| The primitives are drawn pname:instanceCount times with code:instanceIndex |
| starting with pname:firstInstance and increasing sequentially for each |
| instance. |
| The assembled primitives execute the bound graphics pipeline. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/draw_common.adoc[] |
| include::{chapters}/commonvalidity/draw_dispatch_nonindirect_common.adoc[] |
| include::{chapters}/commonvalidity/draw_vertex_binding.adoc[] |
| include::{chapters}/commonvalidity/draw_indexed_common.adoc[] |
| include::{chapters}/commonvalidity/draw_index_binding.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdDrawIndexed.adoc[] |
| -- |
| |
| ifdef::VK_EXT_multi_draw[] |
| [open,refpage='vkCmdDrawMultiEXT',desc='Draw primitives',type='protos'] |
| -- |
| :refpage: vkCmdDrawMultiEXT |
| |
| To record an ordered sequence of draws which have no state changes between |
| them, call: |
| |
| include::{generated}/api/protos/vkCmdDrawMultiEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:drawCount is the number of draws to execute, and can: be zero. |
| * pname:pVertexInfo is a pointer to an array of slink:VkMultiDrawInfoEXT |
| with vertex information to be drawn. |
| * pname:instanceCount is the number of instances per draw. |
| * pname:firstInstance is the instance ID of the first instance in each |
| draw. |
| * pname:stride is the byte stride between consecutive elements of |
| pname:pVertexInfo. |
| |
| The number of draws recorded is pname:drawCount, with each draw reading, |
| sequentially, a pname:firstVertex and a pname:vertexCount from |
| pname:pVertexInfo. |
| For each recorded draw, primitives are assembled as for flink:vkCmdDraw, and |
| drawn pname:instanceCount times with code:instanceIndex starting with |
| pname:firstInstance and sequentially for each instance. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/draw_common.adoc[] |
| include::{chapters}/commonvalidity/draw_dispatch_nonindirect_common.adoc[] |
| include::{chapters}/commonvalidity/draw_vertex_binding.adoc[] |
| * [[VUID-vkCmdDrawMultiEXT-None-04933]] |
| The <<features-multiDraw, pname:multiDraw>> feature must: be enabled |
| * [[VUID-vkCmdDrawMultiEXT-drawCount-04934]] |
| pname:drawCount must: be less than |
| sname:VkPhysicalDeviceMultiDrawPropertiesEXT::pname:maxMultiDrawCount |
| * [[VUID-vkCmdDrawMultiEXT-drawCount-04935]] |
| If pname:drawCount is greater than zero, pname:pVertexInfo must: be a |
| valid pointer to memory containing one or more valid instances of |
| slink:VkMultiDrawInfoEXT structures |
| * [[VUID-vkCmdDrawMultiEXT-stride-04936]] |
| pname:stride must be a multiple of 4 |
| **** |
| |
| include::{generated}/validity/protos/vkCmdDrawMultiEXT.adoc[] |
| -- |
| |
| [open,refpage='vkCmdDrawMultiIndexedEXT',desc='Draw primitives',type='protos'] |
| -- |
| :refpage: vkCmdDrawMultiIndexedEXT |
| |
| To record an ordered sequence of indexed draws which have no state changes |
| between them, call: |
| |
| include::{generated}/api/protos/vkCmdDrawMultiIndexedEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:drawCount is the number of draws to execute, and can: be zero. |
| * pname:pIndexInfo is a pointer to an array of |
| slink:VkMultiDrawIndexedInfoEXT with index information to be drawn. |
| * pname:instanceCount is the number of instances per draw. |
| * pname:firstInstance is the instance ID of the first instance in each |
| draw. |
| * pname:stride is the byte stride between consecutive elements of |
| pname:pIndexInfo. |
| * pname:pVertexOffset is `NULL` or a pointer to the value added to the |
| vertex index before indexing into the vertex buffer. |
| When specified, sname:VkMultiDrawIndexedInfoEXT::pname:offset is |
| ignored. |
| |
| The number of draws recorded is pname:drawCount, with each draw reading, |
| sequentially, a pname:firstIndex and an pname:indexCount from |
| pname:pIndexInfo. |
| For each recorded draw, primitives are assembled as for |
| flink:vkCmdDrawIndexed, and drawn pname:instanceCount times with |
| code:instanceIndex starting with pname:firstInstance and sequentially for |
| each instance. |
| If pname:pVertexOffset is `NULL`, a pname:vertexOffset is also read from |
| pname:pIndexInfo, otherwise the value from dereferencing pname:pVertexOffset |
| is used. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/draw_common.adoc[] |
| include::{chapters}/commonvalidity/draw_dispatch_nonindirect_common.adoc[] |
| include::{chapters}/commonvalidity/draw_vertex_binding.adoc[] |
| include::{chapters}/commonvalidity/draw_indexed_common.adoc[] |
| include::{chapters}/commonvalidity/draw_index_binding.adoc[] |
| * [[VUID-vkCmdDrawMultiIndexedEXT-None-04937]] |
| The <<features-multiDraw, pname:multiDraw>> feature must: be enabled |
| * [[VUID-vkCmdDrawMultiIndexedEXT-drawCount-04939]] |
| pname:drawCount must: be less than |
| sname:VkPhysicalDeviceMultiDrawPropertiesEXT::pname:maxMultiDrawCount |
| * [[VUID-vkCmdDrawMultiIndexedEXT-drawCount-04940]] |
| If pname:drawCount is greater than zero, pname:pIndexInfo must: be a |
| valid pointer to memory containing one or more valid instances of |
| slink:VkMultiDrawIndexedInfoEXT structures |
| * [[VUID-vkCmdDrawMultiIndexedEXT-stride-04941]] |
| pname:stride must be a multiple of 4 |
| **** |
| |
| include::{generated}/validity/protos/vkCmdDrawMultiIndexedEXT.adoc[] |
| -- |
| |
| [open,refpage='VkMultiDrawInfoEXT',desc='Structure specifying a multi-draw command',type='structs',xrefs='vkCmdDrawMultiEXT'] |
| -- |
| The sname:VkMultiDrawInfoEXT structure is defined as: |
| |
| include::{generated}/api/structs/VkMultiDrawInfoEXT.adoc[] |
| |
| * pname:firstVertex is the first vertex to draw. |
| * pname:vertexCount is the number of vertices to draw. |
| |
| The members of sname:VkMultiDrawInfoEXT have the same meaning as the |
| pname:firstVertex and pname:vertexCount parameters in flink:vkCmdDraw. |
| |
| include::{generated}/validity/structs/VkMultiDrawInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkMultiDrawIndexedInfoEXT',desc='Structure specifying a multi-draw command',type='structs',xrefs='vkCmdDrawMultiIndexedEXT'] |
| -- |
| The sname:VkMultiDrawIndexedInfoEXT structure is defined as: |
| |
| include::{generated}/api/structs/VkMultiDrawIndexedInfoEXT.adoc[] |
| |
| * pname:firstIndex is the first index to draw. |
| * pname:indexCount is the number of vertices to draw. |
| * pname:vertexOffset is the value added to the vertex index before |
| indexing into the vertex buffer for indexed multidraws. |
| |
| The pname:firstIndex, pname:indexCount, and pname:vertexOffset members of |
| sname:VkMultiDrawIndexedInfoEXT have the same meaning as the |
| pname:firstIndex, pname:indexCount, and pname:vertexOffset parameters, |
| respectively, of flink:vkCmdDrawIndexed. |
| |
| include::{generated}/validity/structs/VkMultiDrawIndexedInfoEXT.adoc[] |
| |
| -- |
| endif::VK_EXT_multi_draw[] |
| |
| [open,refpage='vkCmdDrawIndirect',desc='Draw primitives with indirect parameters',type='protos'] |
| -- |
| :refpage: vkCmdDrawIndirect |
| |
| To record a non-indexed indirect drawing command, call: |
| |
| include::{generated}/api/protos/vkCmdDrawIndirect.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:buffer is the buffer containing draw parameters. |
| * pname:offset is the byte offset into pname:buffer where parameters |
| begin. |
| * pname:drawCount is the number of draws to execute, and can: be zero. |
| * pname:stride is the byte stride between successive sets of draw |
| parameters. |
| |
| fname:vkCmdDrawIndirect behaves similarly to flink:vkCmdDraw except that the |
| parameters are read by the device from a buffer during execution. |
| pname:drawCount draws are executed by the command, with parameters taken |
| from pname:buffer starting at pname:offset and increasing by pname:stride |
| bytes for each successive draw. |
| The parameters of each draw are encoded in an array of |
| slink:VkDrawIndirectCommand structures. |
| If pname:drawCount is less than or equal to one, pname:stride is ignored. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/draw_common.adoc[] |
| include::{chapters}/commonvalidity/draw_vertex_binding.adoc[] |
| include::{chapters}/commonvalidity/draw_dispatch_indirect_common.adoc[] |
| include::{chapters}/commonvalidity/draw_indirect_drawcount.adoc[] |
| * [[VUID-vkCmdDrawIndirect-drawCount-00476]] |
| If pname:drawCount is greater than `1`, pname:stride must: be a multiple |
| of `4` and must: be greater than or equal to |
| code:sizeof(sname:VkDrawIndirectCommand) |
| * [[VUID-vkCmdDrawIndirect-drawCount-00487]] |
| If pname:drawCount is equal to `1`, [eq]#(pname:offset {plus} |
| code:sizeof(slink:VkDrawIndirectCommand))# must: be less than or equal |
| to the size of pname:buffer |
| * [[VUID-vkCmdDrawIndirect-drawCount-00488]] |
| If pname:drawCount is greater than `1`, [eq]#(pname:stride {times} |
| (pname:drawCount - 1) {plus} pname:offset {plus} |
| code:sizeof(slink:VkDrawIndirectCommand))# must: be less than or equal |
| to the size of pname:buffer |
| **** |
| |
| include::{generated}/validity/protos/vkCmdDrawIndirect.adoc[] |
| -- |
| |
| [open,refpage='VkDrawIndirectCommand',desc='Structure specifying a indirect drawing command',type='structs',xrefs='vkCmdDrawIndirect'] |
| -- |
| The sname:VkDrawIndirectCommand structure is defined as: |
| |
| include::{generated}/api/structs/VkDrawIndirectCommand.adoc[] |
| |
| * pname:vertexCount is the number of vertices to draw. |
| * pname:instanceCount is the number of instances to draw. |
| * pname:firstVertex is the index of the first vertex to draw. |
| * pname:firstInstance is the instance ID of the first instance to draw. |
| |
| The members of sname:VkDrawIndirectCommand have the same meaning as the |
| similarly named parameters of flink:vkCmdDraw. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkDrawIndirectCommand-None-00500]] |
| For a given vertex buffer binding, any attribute data fetched must: be |
| entirely contained within the corresponding vertex buffer binding, as |
| described in <<fxvertex-input>> |
| * [[VUID-VkDrawIndirectCommand-firstInstance-00501]] |
| If the <<features-drawIndirectFirstInstance, |
| pname:drawIndirectFirstInstance>> feature is not enabled, |
| pname:firstInstance must: be code:0 |
| **** |
| |
| include::{generated}/validity/structs/VkDrawIndirectCommand.adoc[] |
| -- |
| |
| ifdef::VK_VERSION_1_2,VK_KHR_draw_indirect_count[] |
| [open,refpage='vkCmdDrawIndirectCount',desc='Draw primitives with indirect parameters and draw count',type='protos',alias='vkCmdDrawIndirectCountKHR vkCmdDrawIndirectCountAMD'] |
| -- |
| :refpage: vkCmdDrawIndirectCount |
| |
| To record a non-indexed draw call with a draw call count sourced from a |
| buffer, call: |
| |
| ifdef::VK_VERSION_1_2[] |
| include::{generated}/api/protos/vkCmdDrawIndirectCount.adoc[] |
| endif::VK_VERSION_1_2[] |
| |
| // Jon: conditional logic on connective clauses with 3 forms of the command including VK_VERSION_1_2 needs work. |
| ifdef::VK_VERSION_1_2+VK_KHR_draw_indirect_count[or the equivalent command] |
| |
| ifdef::VK_KHR_draw_indirect_count[] |
| include::{generated}/api/protos/vkCmdDrawIndirectCountKHR.adoc[] |
| endif::VK_KHR_draw_indirect_count[] |
| |
| ifdef::VK_KHR_draw_indirect_count+VK_AMD_draw_indirect_count[or the equivalent command] |
| |
| ifdef::VK_AMD_draw_indirect_count[] |
| include::{generated}/api/protos/vkCmdDrawIndirectCountAMD.adoc[] |
| endif::VK_AMD_draw_indirect_count[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:buffer is the buffer containing draw parameters. |
| * pname:offset is the byte offset into pname:buffer where parameters |
| begin. |
| * pname:countBuffer is the buffer containing the draw count. |
| * pname:countBufferOffset is the byte offset into pname:countBuffer where |
| the draw count begins. |
| * pname:maxDrawCount specifies the maximum number of draws that will be |
| executed. |
| The actual number of executed draw calls is the minimum of the count |
| specified in pname:countBuffer and pname:maxDrawCount. |
| * pname:stride is the byte stride between successive sets of draw |
| parameters. |
| |
| fname:vkCmdDrawIndirectCount behaves similarly to flink:vkCmdDrawIndirect |
| except that the draw count is read by the device from a buffer during |
| execution. |
| The command will read an unsigned 32-bit integer from pname:countBuffer |
| located at pname:countBufferOffset and use this as the draw count. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/draw_common.adoc[] |
| include::{chapters}/commonvalidity/draw_vertex_binding.adoc[] |
| include::{chapters}/commonvalidity/draw_dispatch_indirect_common.adoc[] |
| include::{chapters}/commonvalidity/draw_indirect_count_common.adoc[] |
| * [[VUID-vkCmdDrawIndirectCount-stride-03110]] |
| pname:stride must: be a multiple of `4` and must: be greater than or |
| equal to sizeof(sname:VkDrawIndirectCommand) |
| * [[VUID-vkCmdDrawIndirectCount-maxDrawCount-03111]] |
| If pname:maxDrawCount is greater than or equal to `1`, |
| [eq]#(pname:stride {times} (pname:maxDrawCount - 1) {plus} pname:offset |
| {plus} sizeof(sname:VkDrawIndirectCommand))# must: be less than or equal |
| to the size of pname:buffer |
| * [[VUID-vkCmdDrawIndirectCount-countBuffer-03121]] |
| If the count stored in pname:countBuffer is equal to `1`, |
| [eq]#(pname:offset {plus} sizeof(sname:VkDrawIndirectCommand))# must: be |
| less than or equal to the size of pname:buffer |
| * [[VUID-vkCmdDrawIndirectCount-countBuffer-03122]] |
| If the count stored in pname:countBuffer is greater than `1`, |
| [eq]#(pname:stride {times} (pname:drawCount - 1) {plus} pname:offset |
| {plus} sizeof(sname:VkDrawIndirectCommand))# must: be less than or equal |
| to the size of pname:buffer |
| **** |
| |
| include::{generated}/validity/protos/vkCmdDrawIndirectCount.adoc[] |
| |
| -- |
| endif::VK_VERSION_1_2,VK_KHR_draw_indirect_count[] |
| |
| [open,refpage='vkCmdDrawIndexedIndirect',desc='Draw primitives with indirect parameters and indexed vertices',type='protos'] |
| -- |
| :refpage: vkCmdDrawIndexedIndirect |
| |
| To record an indexed indirect drawing command, call: |
| |
| include::{generated}/api/protos/vkCmdDrawIndexedIndirect.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:buffer is the buffer containing draw parameters. |
| * pname:offset is the byte offset into pname:buffer where parameters |
| begin. |
| * pname:drawCount is the number of draws to execute, and can: be zero. |
| * pname:stride is the byte stride between successive sets of draw |
| parameters. |
| |
| fname:vkCmdDrawIndexedIndirect behaves similarly to flink:vkCmdDrawIndexed |
| except that the parameters are read by the device from a buffer during |
| execution. |
| pname:drawCount draws are executed by the command, with parameters taken |
| from pname:buffer starting at pname:offset and increasing by pname:stride |
| bytes for each successive draw. |
| The parameters of each draw are encoded in an array of |
| slink:VkDrawIndexedIndirectCommand structures. |
| If pname:drawCount is less than or equal to one, pname:stride is ignored. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/draw_common.adoc[] |
| include::{chapters}/commonvalidity/draw_vertex_binding.adoc[] |
| include::{chapters}/commonvalidity/draw_dispatch_indirect_common.adoc[] |
| include::{chapters}/commonvalidity/draw_indirect_drawcount.adoc[] |
| include::{chapters}/commonvalidity/draw_indexed_common.adoc[] |
| * [[VUID-vkCmdDrawIndexedIndirect-drawCount-00528]] |
| If pname:drawCount is greater than `1`, pname:stride must: be a multiple |
| of `4` and must: be greater than or equal to |
| code:sizeof(sname:VkDrawIndexedIndirectCommand) |
| * [[VUID-vkCmdDrawIndexedIndirect-drawCount-00539]] |
| If pname:drawCount is equal to `1`, [eq]#(pname:offset {plus} |
| code:sizeof(sname:VkDrawIndexedIndirectCommand))# must: be less than or |
| equal to the size of pname:buffer |
| * [[VUID-vkCmdDrawIndexedIndirect-drawCount-00540]] |
| If pname:drawCount is greater than `1`, [eq]#(pname:stride {times} |
| (pname:drawCount - 1) {plus} pname:offset {plus} |
| code:sizeof(sname:VkDrawIndexedIndirectCommand))# must: be less than or |
| equal to the size of pname:buffer |
| **** |
| |
| include::{generated}/validity/protos/vkCmdDrawIndexedIndirect.adoc[] |
| -- |
| |
| [open,refpage='VkDrawIndexedIndirectCommand',desc='Structure specifying a indexed indirect drawing command',type='structs',xrefs='vkCmdDrawIndexedIndirect'] |
| -- |
| :refpage: VkDrawIndexedIndirectCommand |
| |
| The sname:VkDrawIndexedIndirectCommand structure is defined as: |
| |
| include::{generated}/api/structs/VkDrawIndexedIndirectCommand.adoc[] |
| |
| * pname:indexCount is the number of vertices to draw. |
| * pname:instanceCount is the number of instances to draw. |
| * pname:firstIndex is the base index within the index buffer. |
| * pname:vertexOffset is the value added to the vertex index before |
| indexing into the vertex buffer. |
| * pname:firstInstance is the instance ID of the first instance to draw. |
| |
| The members of sname:VkDrawIndexedIndirectCommand have the same meaning as |
| the similarly named parameters of flink:vkCmdDrawIndexed. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/draw_index_binding.adoc[] |
| * [[VUID-VkDrawIndexedIndirectCommand-None-00552]] |
| For a given vertex buffer binding, any attribute data fetched must: be |
| entirely contained within the corresponding vertex buffer binding, as |
| described in <<fxvertex-input>> |
| * [[VUID-VkDrawIndexedIndirectCommand-firstInstance-00554]] |
| If the <<features-drawIndirectFirstInstance, |
| pname:drawIndirectFirstInstance>> feature is not enabled, |
| pname:firstInstance must: be code:0 |
| **** |
| |
| include::{generated}/validity/structs/VkDrawIndexedIndirectCommand.adoc[] |
| -- |
| |
| ifdef::VK_VERSION_1_2,VK_KHR_draw_indirect_count[] |
| [open,refpage='vkCmdDrawIndexedIndirectCount',desc='Draw parameters with indirect parameters, indexed vertices, and draw count',type='protos',alias='vkCmdDrawIndexedIndirectCountKHR vkCmdDrawIndexedIndirectCountAMD'] |
| -- |
| :refpage: vkCmdDrawIndexedIndirectCount |
| |
| To record an indexed draw call with a draw call count sourced from a buffer, |
| call: |
| |
| ifdef::VK_VERSION_1_2[] |
| include::{generated}/api/protos/vkCmdDrawIndexedIndirectCount.adoc[] |
| endif::VK_VERSION_1_2[] |
| |
| // Jon: conditional logic on connective clauses with 3 forms of the command including VK_VERSION_1_2 needs work. |
| ifdef::VK_VERSION_1_2+VK_KHR_draw_indirect_count[or the equivalent command] |
| |
| ifdef::VK_KHR_draw_indirect_count[] |
| include::{generated}/api/protos/vkCmdDrawIndexedIndirectCountKHR.adoc[] |
| endif::VK_KHR_draw_indirect_count[] |
| |
| ifdef::VK_KHR_draw_indirect_count+VK_AMD_draw_indirect_count[or the equivalent command] |
| |
| ifdef::VK_AMD_draw_indirect_count[] |
| include::{generated}/api/protos/vkCmdDrawIndexedIndirectCountAMD.adoc[] |
| endif::VK_AMD_draw_indirect_count[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:buffer is the buffer containing draw parameters. |
| * pname:offset is the byte offset into pname:buffer where parameters |
| begin. |
| * pname:countBuffer is the buffer containing the draw count. |
| * pname:countBufferOffset is the byte offset into pname:countBuffer where |
| the draw count begins. |
| * pname:maxDrawCount specifies the maximum number of draws that will be |
| executed. |
| The actual number of executed draw calls is the minimum of the count |
| specified in pname:countBuffer and pname:maxDrawCount. |
| * pname:stride is the byte stride between successive sets of draw |
| parameters. |
| |
| fname:vkCmdDrawIndexedIndirectCount behaves similarly to |
| flink:vkCmdDrawIndexedIndirect except that the draw count is read by the |
| device from a buffer during execution. |
| The command will read an unsigned 32-bit integer from pname:countBuffer |
| located at pname:countBufferOffset and use this as the draw count. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/draw_common.adoc[] |
| include::{chapters}/commonvalidity/draw_vertex_binding.adoc[] |
| include::{chapters}/commonvalidity/draw_dispatch_indirect_common.adoc[] |
| include::{chapters}/commonvalidity/draw_indirect_count_common.adoc[] |
| include::{chapters}/commonvalidity/draw_indexed_common.adoc[] |
| * [[VUID-vkCmdDrawIndexedIndirectCount-stride-03142]] |
| pname:stride must: be a multiple of `4` and must: be greater than or |
| equal to sizeof(sname:VkDrawIndexedIndirectCommand) |
| * [[VUID-vkCmdDrawIndexedIndirectCount-maxDrawCount-03143]] |
| If pname:maxDrawCount is greater than or equal to `1`, |
| [eq]#(pname:stride {times} (pname:maxDrawCount - 1) {plus} pname:offset |
| {plus} sizeof(sname:VkDrawIndexedIndirectCommand))# must: be less than |
| or equal to the size of pname:buffer |
| * [[VUID-vkCmdDrawIndexedIndirectCount-countBuffer-03153]] |
| If count stored in pname:countBuffer is equal to `1`, [eq]#(pname:offset |
| {plus} sizeof(sname:VkDrawIndexedIndirectCommand))# must: be less than |
| or equal to the size of pname:buffer |
| * [[VUID-vkCmdDrawIndexedIndirectCount-countBuffer-03154]] |
| If count stored in pname:countBuffer is greater than `1`, |
| [eq]#(pname:stride {times} (pname:drawCount - 1) {plus} pname:offset |
| {plus} sizeof(sname:VkDrawIndexedIndirectCommand))# must: be less than |
| or equal to the size of pname:buffer |
| **** |
| |
| include::{generated}/validity/protos/vkCmdDrawIndexedIndirectCount.adoc[] |
| -- |
| endif::VK_VERSION_1_2,VK_KHR_draw_indirect_count[] |
| |
| |
| ifdef::VK_EXT_transform_feedback[] |
| [[drawing-transform-feedback]] |
| === Drawing Transform Feedback |
| |
| It is possible to draw vertex data that was previously captured during |
| active <<vertexpostproc-transform-feedback,transform feedback>> by binding |
| one or more of the transform feedback buffers as vertex buffers. |
| A pipeline barrier is required between using the buffers as transform |
| feedback buffers and vertex buffers to ensure all writes to the transform |
| feedback buffers are visible when the data is read as vertex attributes. |
| The source access is ename:VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT and |
| the destination access is ename:VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT for the |
| pipeline stages ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT and |
| ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT respectively. |
| The value written to the counter buffer by |
| flink:vkCmdEndTransformFeedbackEXT can: be used to determine the vertex |
| count for the draw. |
| A pipeline barrier is required between using the counter buffer for |
| fname:vkCmdEndTransformFeedbackEXT and fname:vkCmdDrawIndirectByteCountEXT |
| where the source access is |
| ename:VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT and the destination |
| access is ename:VK_ACCESS_INDIRECT_COMMAND_READ_BIT for the pipeline stages |
| ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT and |
| ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT respectively. |
| |
| [open,refpage='vkCmdDrawIndirectByteCountEXT',desc='Draw primitives with indirect parameters where the vertex count is derived from the counter byte value in the counter buffer',type='protos'] |
| -- |
| :refpage: vkCmdDrawIndirectByteCountEXT |
| |
| To record a non-indexed draw call, where the vertex count is based on a byte |
| count read from a buffer and the passed in vertex stride parameter, call: |
| |
| include::{generated}/api/protos/vkCmdDrawIndirectByteCountEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:instanceCount is the number of instances to draw. |
| * pname:firstInstance is the instance ID of the first instance to draw. |
| * pname:counterBuffer is the buffer handle from where the byte count is |
| read. |
| * pname:counterBufferOffset is the offset into the buffer used to read the |
| byte count, which is used to calculate the vertex count for this draw |
| call. |
| * pname:counterOffset is subtracted from the byte count read from the |
| pname:counterBuffer at the pname:counterBufferOffset |
| * pname:vertexStride is the stride in bytes between each element of the |
| vertex data that is used to calculate the vertex count from the counter |
| value. |
| This value is typically the same value that was used in the graphics |
| pipeline state when the transform feedback was captured as the |
| code:XfbStride. |
| |
| When the command is executed, primitives are assembled in the same way as |
| done with flink:vkCmdDraw except the pname:vertexCount is calculated based |
| on the byte count read from pname:counterBuffer at offset |
| pname:counterBufferOffset. |
| The assembled primitives execute the bound graphics pipeline. |
| |
| The effective pname:vertexCount is calculated as follows: |
| |
| [source,c] |
| ---- |
| const uint32_t * counterBufferPtr = (const uint8_t *)counterBuffer.address + counterBufferOffset; |
| vertexCount = floor(max(0, (*counterBufferPtr - counterOffset)) / vertexStride); |
| ---- |
| |
| The effective pname:firstVertex is zero. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/draw_common.adoc[] |
| include::{chapters}/commonvalidity/draw_vertex_binding.adoc[] |
| * [[VUID-vkCmdDrawIndirectByteCountEXT-transformFeedback-02287]] |
| sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:transformFeedback |
| must: be enabled |
| * [[VUID-vkCmdDrawIndirectByteCountEXT-transformFeedbackDraw-02288]] |
| The implementation must: support |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:transformFeedbackDraw |
| * [[VUID-vkCmdDrawIndirectByteCountEXT-vertexStride-02289]] |
| pname:vertexStride must: be greater than 0 and less than or equal to |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBufferDataStride |
| * [[VUID-vkCmdDrawIndirectByteCountEXT-counterBuffer-04567]] |
| If pname:counterBuffer is non-sparse then it must: be bound completely |
| and contiguously to a single sname:VkDeviceMemory object |
| * [[VUID-vkCmdDrawIndirectByteCountEXT-counterBuffer-02290]] |
| pname:counterBuffer must: have been created with the |
| ename:VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set |
| * [[VUID-vkCmdDrawIndirectByteCountEXT-counterBufferOffset-04568]] |
| pname:counterBufferOffset must: be a multiple of `4` |
| ifdef::VK_VERSION_1_1[] |
| * [[VUID-vkCmdDrawIndirectByteCountEXT-commandBuffer-02646]] |
| pname:commandBuffer must: not be a protected command buffer |
| endif::VK_VERSION_1_1[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdDrawIndirectByteCountEXT.adoc[] |
| -- |
| endif::VK_EXT_transform_feedback[] |
| |
| |
| ifdef::VK_EXT_conditional_rendering[] |
| [[drawing-conditional-rendering]] |
| == Conditional Rendering |
| |
| Certain rendering commands can: be executed conditionally based on a value |
| in buffer memory. |
| These rendering commands are limited to <<drawing,drawing commands>>, |
| <<dispatch,dispatching commands>>, and clearing attachments with |
| flink:vkCmdClearAttachments within a conditional rendering block which is |
| defined by commands flink:vkCmdBeginConditionalRenderingEXT and |
| flink:vkCmdEndConditionalRenderingEXT. |
| Other rendering commands remain unaffected by conditional rendering. |
| |
| [[active-conditional-rendering]] |
| After beginning conditional rendering, it is considered _active_ within the |
| command buffer it was called until it is ended with |
| flink:vkCmdEndConditionalRenderingEXT. |
| |
| Conditional rendering must: begin and end in the same command buffer. |
| When conditional rendering is active, a primary command buffer can: execute |
| secondary command buffers if the <<features-inheritedConditionalRendering, |
| pname:inheritedConditionalRendering>> feature is enabled. |
| For a secondary command buffer to be executed while conditional rendering is |
| active in the primary command buffer, it must: set the |
| pname:conditionalRenderingEnable flag of |
| slink:VkCommandBufferInheritanceConditionalRenderingInfoEXT, as described in |
| the <<commandbuffers-recording, Command Buffer Recording>> section. |
| |
| Conditional rendering must: also either begin and end inside the same |
| subpass of a render pass instance, or must: both begin and end outside of a |
| render pass instance (i.e. contain entire render pass instances). |
| |
| [open,refpage='vkCmdBeginConditionalRenderingEXT',desc='Define the beginning of a conditional rendering block',type='protos'] |
| -- |
| To begin conditional rendering, call: |
| |
| include::{generated}/api/protos/vkCmdBeginConditionalRenderingEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which this command will |
| be recorded. |
| * pname:pConditionalRenderingBegin is a pointer to a |
| slink:VkConditionalRenderingBeginInfoEXT structure specifying parameters |
| of conditional rendering. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdBeginConditionalRenderingEXT-None-01980]] |
| Conditional rendering must: not already be |
| <<active-conditional-rendering,active>> |
| **** |
| |
| include::{generated}/validity/protos/vkCmdBeginConditionalRenderingEXT.adoc[] |
| -- |
| |
| [open,refpage='VkConditionalRenderingBeginInfoEXT',desc='Structure specifying conditional rendering begin information',type='structs'] |
| -- |
| The sname:VkConditionalRenderingBeginInfoEXT structure is defined as: |
| |
| include::{generated}/api/structs/VkConditionalRenderingBeginInfoEXT.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:buffer is a buffer containing the predicate for conditional |
| rendering. |
| * pname:offset is the byte offset into pname:buffer where the predicate is |
| located. |
| * pname:flags is a bitmask of tlink:VkConditionalRenderingFlagsEXT |
| specifying the behavior of conditional rendering. |
| |
| If the 32-bit value at pname:offset in pname:buffer memory is zero, then the |
| rendering commands are discarded, otherwise they are executed as normal. |
| If the value of the predicate in buffer memory changes while conditional |
| rendering is active, the rendering commands may: be discarded in an |
| implementation-dependent way. |
| Some implementations may latch the value of the predicate upon beginning |
| conditional rendering while others may read it before every rendering |
| command. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkConditionalRenderingBeginInfoEXT-buffer-01981]] |
| If pname:buffer is non-sparse then it must: be bound completely and |
| contiguously to a single sname:VkDeviceMemory object |
| * [[VUID-VkConditionalRenderingBeginInfoEXT-buffer-01982]] |
| pname:buffer must: have been created with the |
| ename:VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT bit set |
| * [[VUID-VkConditionalRenderingBeginInfoEXT-offset-01983]] |
| pname:offset must: be less than the size of pname:buffer by at least 32 |
| bits |
| * [[VUID-VkConditionalRenderingBeginInfoEXT-offset-01984]] |
| pname:offset must: be a multiple of 4 |
| **** |
| |
| include::{generated}/validity/structs/VkConditionalRenderingBeginInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkConditionalRenderingFlagBitsEXT',desc='Specify the behavior of conditional rendering',type='enums'] |
| -- |
| Bits which can: be set in |
| flink:vkCmdBeginConditionalRenderingEXT::pname:flags, specifying the |
| behavior of conditional rendering, are: |
| |
| include::{generated}/api/enums/VkConditionalRenderingFlagBitsEXT.adoc[] |
| |
| * ename:VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT specifies the condition |
| used to determine whether to discard rendering commands or not. |
| That is, if the 32-bit predicate read from pname:buffer memory at |
| pname:offset is zero, the rendering commands are not discarded, and if |
| non zero, then they are discarded. |
| -- |
| |
| [open,refpage='VkConditionalRenderingFlagsEXT',desc='Bitmask of VkConditionalRenderingFlagBitsEXT',type='flags'] |
| -- |
| include::{generated}/api/flags/VkConditionalRenderingFlagsEXT.adoc[] |
| |
| tname:VkConditionalRenderingFlagsEXT is a bitmask type for setting a mask of |
| zero or more elink:VkConditionalRenderingFlagBitsEXT. |
| -- |
| |
| [open,refpage='vkCmdEndConditionalRenderingEXT',desc='Define the end of a conditional rendering block',type='protos'] |
| -- |
| To end conditional rendering, call: |
| |
| include::{generated}/api/protos/vkCmdEndConditionalRenderingEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which this command will |
| be recorded. |
| |
| Once ended, conditional rendering becomes inactive. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdEndConditionalRenderingEXT-None-01985]] |
| Conditional rendering must: be <<active-conditional-rendering,active>> |
| * [[VUID-vkCmdEndConditionalRenderingEXT-None-01986]] |
| If conditional rendering was made |
| <<active-conditional-rendering,active>> outside of a render pass |
| instance, it must: not be ended inside a render pass instance |
| * [[VUID-vkCmdEndConditionalRenderingEXT-None-01987]] |
| If conditional rendering was made |
| <<active-conditional-rendering,active>> within a subpass it must: be |
| ended in the same subpass |
| **** |
| |
| include::{generated}/validity/protos/vkCmdEndConditionalRenderingEXT.adoc[] |
| -- |
| endif::VK_EXT_conditional_rendering[] |
| |
| ifdef::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| include::{chapters}/VK_NV_mesh_shader/drawing.adoc[] |
| endif::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| |
| ifdef::VK_HUAWEI_cluster_culling_shader[] |
| include::{chapters}/VK_HUAWEI_cluster_culling_shader/drawing.adoc[] |
| endif::VK_HUAWEI_cluster_culling_shader[] |