1242 lines
50 KiB
Plaintext
1242 lines
50 KiB
Plaintext
// Copyright (c) 2015-2019 Khronos Group. This work is licensed under a
|
|
// Creative Commons Attribution 4.0 International License; see
|
|
// http://creativecommons.org/licenses/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
|
|
pipeline.
|
|
A graphics pipeline 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[]
|
|
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[]
|
|
|
|
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 sname:VkGraphicsPipelineCreateInfo structure, which is of type
|
|
sname:VkPipelineInputAssemblyStateCreateInfo:
|
|
|
|
include::{generated}/api/structs/VkPipelineInputAssemblyStateCreateInfo.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific 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 and
|
|
flink:vkCmdDrawIndexedIndirect), and the special index value is either
|
|
0xFFFFFFFF when the pname:indexType parameter of
|
|
fname:vkCmdBindIndexBuffer is equal to ename:VK_INDEX_TYPE_UINT32, or
|
|
0xFFFF when pname:indexType is equal to ename:VK_INDEX_TYPE_UINT16.
|
|
Primitive restart is not allowed for "`list`" topologies.
|
|
|
|
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-00428]]
|
|
If 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,
|
|
ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or
|
|
ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, pname:primitiveRestartEnable
|
|
must: be ename:VK_FALSE
|
|
* [[VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00429]]
|
|
If the <<features-geometryShader,geometry shaders>> 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,tessellation shaders>> feature is
|
|
not enabled, pname:topology must: not be
|
|
ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
|
|
****
|
|
|
|
include::{generated}/validity/structs/VkPipelineInputAssemblyStateCreateInfo.txt[]
|
|
--
|
|
|
|
[open,refpage='VkPipelineInputAssemblyStateCreateFlags',desc='Reserved for future use',type='flags']
|
|
--
|
|
include::{generated}/api/flags/VkPipelineInputAssemblyStateCreateFlags.txt[]
|
|
|
|
tname:VkPipelineInputAssemblyStateCreateFlags is a bitmask type for setting
|
|
a mask, but is currently reserved for future use.
|
|
--
|
|
|
|
|
|
[[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[]
|
|
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[]
|
|
|
|
[open,refpage='VkPrimitiveTopology',desc='Supported primitive topologies',type='enums']
|
|
--
|
|
|
|
The primitive topologies defined by elink:VkPrimitiveTopology are:
|
|
|
|
include::{generated}/api/enums/VkPrimitiveTopology.txt[]
|
|
|
|
* 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.
|
|
* ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY specifies a series
|
|
<<drawing-line-lists-with-adjacency,separate line primitives with
|
|
adjacency>>.
|
|
* ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY specifies a series
|
|
<<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 <<drawing-line-lists-with-adjacency,separate triangle primitives
|
|
with adjacency>>.
|
|
* ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY specifies
|
|
<<drawing-line-lists-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[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[opts="{imageopts}"]
|
|
.^| Vertex Number
|
|
| Sequence position of a vertex within the provided vertex data.
|
|
|
|
^.^| image:{images}/primitive_topology_key_provoking_vertex.svg[opts="{imageopts}"]
|
|
.^| Provoking Vertex
|
|
| Provoking vertex within the main primitive.
|
|
The arrow points along an edge of the relevant primitive, following winding order.
|
|
Used in <<vertexpostproc-flatshading, flat shading>>.
|
|
|
|
^.^| image:{images}/primitive_topology_key_edge.svg[opts="{imageopts}"]
|
|
.^| Primitive Edge
|
|
| An edge connecting the points of a main primitive.
|
|
|
|
^.^| image:{images}/primitive_topology_key_adjacency_edge.svg[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[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.
|
|
--
|
|
|
|
|
|
[[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:
|
|
|
|
:: [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 pname:topology is ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST, each
|
|
consecutive pair of vertices defines a single line primitive, according to
|
|
the equation:
|
|
|
|
:: [eq]#p~i~ = {v~2i~, v~2i+1~}#
|
|
|
|
The provoking vertex for [eq]#p~i~# is [eq]#v~2i~#.
|
|
The number of primitives generated is equal to
|
|
[eq]#{lfloor}pname:vertexCount/2{rfloor}#.
|
|
|
|
image::{images}/primitive_topology_line_list.svg[align="center",opts="{imageopts}"]
|
|
|
|
|
|
[[drawing-line-strips]]
|
|
=== Line Strips
|
|
|
|
When the pname:topology is ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, one line
|
|
primitive is defined by each vertex and the following vertex, according to
|
|
the equation:
|
|
|
|
:: [eq]#p~i~ = {v~i~, v~i+1~}#
|
|
|
|
The provoking vertex for [eq]#p~i~# is [eq]#v~i~#.
|
|
The number of primitives generated is equal to
|
|
[eq]#max(0,pname:vertexCount-1)#.
|
|
|
|
|
|
image::{images}/primitive_topology_line_strip.svg[align="center",opts="{imageopts}"]
|
|
|
|
|
|
[[drawing-triangle-lists]]
|
|
=== Triangle Lists
|
|
|
|
When the pname:topology is ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, each
|
|
consecutive set of three vertices defines a single triangle primitive,
|
|
according to the equation:
|
|
|
|
:: [eq]#p~i~ = {v~3i~, v~3i+1~, v~3i+2~}#
|
|
|
|
The provoking vertex for [eq]#p~i~# is [eq]#v~3i~#.
|
|
The number of primitives generated is equal to
|
|
[eq]#{lfloor}pname:vertexCount/3{rfloor}#.
|
|
|
|
image::{images}/primitive_topology_triangle_list.svg[align="center",opts="{imageopts}"]
|
|
|
|
|
|
[[drawing-triangle-strips]]
|
|
=== Triangle Strips
|
|
|
|
When the pname: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:
|
|
|
|
:: [eq]#p~i~ = {v~i~, v~i+(1+i%2)~, v~i+(2-i%2)~}#
|
|
|
|
The provoking vertex for [eq]#p~i~# is [eq]#v~i~#.
|
|
The number of primitives generated is equal to
|
|
[eq]#max(0,pname:vertexCount-2)#.
|
|
|
|
image::{images}/primitive_topology_triangle_strip.svg[align="center",opts="{imageopts}"]
|
|
|
|
[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 pname:topology is ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
|
|
triangle primitives are defined around a shared common vertex, according to
|
|
the equation:
|
|
|
|
:: [eq]#p~i~ = {v~i+1~, v~i+2~, v~0~}#
|
|
|
|
The provoking vertex for [eq]#p~i~# is [eq]#v~i+1~#.
|
|
The number of primitives generated is equal to
|
|
[eq]#max(0,pname:vertexCount-2)#.
|
|
|
|
image::{images}/primitive_topology_triangle_fan.svg[align="center",opts="{imageopts}"]
|
|
|
|
|
|
[[drawing-line-lists-with-adjacency]]
|
|
=== Line Lists With Adjacency
|
|
|
|
When the pname: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:
|
|
|
|
:: [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 provoking vertex for [eq]#p~i~# is [eq]#v~4i+1~#.
|
|
The number of primitives generated is equal to
|
|
[eq]#{lfloor}pname:vertexCount/4{rfloor}#.
|
|
|
|
image::{images}/primitive_topology_line_list_with_adjacency.svg[align="center",opts="{imageopts}"]
|
|
|
|
|
|
[[drawing-line-strips-with-adjacency]]
|
|
=== Line Strips With Adjacency
|
|
|
|
When the pname: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:
|
|
|
|
:: [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 provoking vertex for [eq]#p~i~# is [eq]#v~i+1~#.
|
|
The number of primitives generated is equal to
|
|
[eq]#max(0,pname:vertexCount-3)#.
|
|
|
|
image::{images}/primitive_topology_line_strip_with_adjacency.svg[align="center",opts="{imageopts}"]
|
|
|
|
|
|
[[drawing-triangle-lists-with-adjacency]]
|
|
=== Triangle Lists With Adjacency
|
|
|
|
When the pname: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:
|
|
|
|
:: [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 provoking vertex for [eq]#p~i~# is [eq]#v~6i~#.
|
|
The number of primitives generated is equal to
|
|
[eq]#{lfloor}pname:vertexCount/6{rfloor}#.
|
|
|
|
image::{images}/primitive_topology_triangle_list_with_adjacency.svg[align="center",opts="{imageopts}"]
|
|
|
|
|
|
[[drawing-triangle-strips-with-adjacency]]
|
|
=== Triangle Strips With Adjacency
|
|
|
|
When the pname: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:
|
|
|
|
:: [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:
|
|
|
|
:: [eq]#p~i~ = {v~2i~, v~2i+1~, v~2i+2~, v~2i+6~, v~2i+4~, v~2i+3~}# when
|
|
[eq]#i=0#
|
|
:: [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#
|
|
:: [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#
|
|
:: [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#
|
|
:: [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.
|
|
====
|
|
|
|
The provoking vertex for [eq]#p~i~# is always [eq]#v~2i~#.
|
|
|
|
image::{images}/primitive_topology_triangle_strip_with_adjacency.svg[align="center",opts="{imageopts}"]
|
|
|
|
|
|
[[drawing-patch-lists]]
|
|
=== Patch Lists
|
|
|
|
When the pname:topology is ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, each
|
|
consecutive set of [eq]#m# vertices defines a single patch primitive,
|
|
according to the equation:
|
|
|
|
:: [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-stages-types, graphics pipeline>>
|
|
in _primitive order_.
|
|
Primitive order is initially determined in the following way:
|
|
|
|
. Submission order determines the initial ordering
|
|
. For indirect draw 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 draw 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 draw 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[]
|
|
** For draws using mesh shaders, the order is provided by <<mesh-ordering,
|
|
mesh shading>>.
|
|
endif::VK_NV_mesh_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 <<primrast-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_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[]
|
|
* 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_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[]
|
|
|
|
|
|
[open,refpage='vkCmdBindIndexBuffer',desc='Bind an index buffer to a command buffer',type='protos']
|
|
--
|
|
|
|
To bind an index buffer to a command buffer, call:
|
|
|
|
include::{generated}/api/protos/vkCmdBindIndexBuffer.txt[]
|
|
|
|
* 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 whether indices
|
|
are treated as 16 bits or 32 bits.
|
|
|
|
.Valid Usage
|
|
****
|
|
* [[VUID-vkCmdBindIndexBuffer-offset-00431]]
|
|
pname:offset must: be less than the size of pname:buffer
|
|
* [[VUID-vkCmdBindIndexBuffer-offset-00432]]
|
|
The sum of pname:offset and the address of the range of
|
|
sname:VkDeviceMemory object that is backing pname:buffer, must: be a
|
|
multiple of the type indicated by pname:indexType
|
|
* [[VUID-vkCmdBindIndexBuffer-buffer-00433]]
|
|
pname:buffer must: have been created with the
|
|
ename:VK_BUFFER_USAGE_INDEX_BUFFER_BIT flag
|
|
* [[VUID-vkCmdBindIndexBuffer-buffer-00434]]
|
|
If pname:buffer is non-sparse then it must: be bound completely and
|
|
contiguously to a single sname:VkDeviceMemory object
|
|
ifdef::VK_NV_ray_tracing[]
|
|
* [[VUID-vkCmdBindIndexBuffer-indexType-02507]]
|
|
pname:indexType must: not be ename:VK_INDEX_TYPE_NONE_NV.
|
|
endif::VK_NV_ray_tracing[]
|
|
****
|
|
|
|
include::{generated}/validity/protos/vkCmdBindIndexBuffer.txt[]
|
|
--
|
|
|
|
|
|
[open,refpage='VkIndexType',desc='Type of index buffer indices',type='enums']
|
|
--
|
|
|
|
Possible values of flink:vkCmdBindIndexBuffer::pname:indexType, specifying
|
|
the size of indices, are:
|
|
|
|
include::{generated}/api/enums/VkIndexType.txt[]
|
|
|
|
* 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[]
|
|
* ename:VK_INDEX_TYPE_NONE_NV specifies that no indices are provided.
|
|
endif::VK_NV_ray_tracing[]
|
|
--
|
|
|
|
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, Robust
|
|
Buffer Access>> feature.
|
|
|
|
[open,refpage='vkCmdDraw',desc='Draw primitives',type='protos']
|
|
--
|
|
:refpage: vkCmdDraw
|
|
|
|
To record a non-indexed draw, call:
|
|
|
|
include::{generated}/api/protos/vkCmdDraw.txt[]
|
|
|
|
* 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.txt[]
|
|
include::{chapters}/commonvalidity/draw_dispatch_nonindirect_common.txt[]
|
|
include::{chapters}/commonvalidity/draw_vertex_binding.txt[]
|
|
****
|
|
|
|
include::{generated}/validity/protos/vkCmdDraw.txt[]
|
|
--
|
|
|
|
[open,refpage='vkCmdDrawIndexed',desc='Issue an indexed draw into a command buffer',type='protos']
|
|
--
|
|
:refpage: vkCmdDrawIndexed
|
|
|
|
To record an indexed draw, call:
|
|
|
|
include::{generated}/api/protos/vkCmdDrawIndexed.txt[]
|
|
|
|
* 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 flink:vkCmdBindIndexBuffer::pname:indexType parameter
|
|
with which the buffer was bound.
|
|
|
|
The first vertex index is at an offset of pname:firstIndex * code:indexSize
|
|
+ pname:offset within the bound index buffer, where pname:offset is the
|
|
offset specified by fname:vkCmdBindIndexBuffer 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 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.txt[]
|
|
include::{chapters}/commonvalidity/draw_dispatch_nonindirect_common.txt[]
|
|
include::{chapters}/commonvalidity/draw_vertex_binding.txt[]
|
|
* [[VUID-vkCmdDrawIndexed-indexSize-00463]]
|
|
[eq]#(code:indexSize * (pname:firstIndex {plus} pname:indexCount) {plus}
|
|
pname:offset)# must: be less than or equal to the size of the bound
|
|
index buffer, with code:indexSize being based on the type specified by
|
|
pname:indexType, where the index buffer, pname:indexType, and
|
|
pname:offset are specified via fname:vkCmdBindIndexBuffer
|
|
****
|
|
|
|
include::{generated}/validity/protos/vkCmdDrawIndexed.txt[]
|
|
--
|
|
|
|
[open,refpage='vkCmdDrawIndirect',desc='Issue an indirect draw into a command buffer',type='protos']
|
|
--
|
|
:refpage: vkCmdDrawIndirect
|
|
|
|
To record a non-indexed indirect draw, call:
|
|
|
|
include::{generated}/api/protos/vkCmdDrawIndirect.txt[]
|
|
|
|
* 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.txt[]
|
|
include::{chapters}/commonvalidity/draw_vertex_binding.txt[]
|
|
include::{chapters}/commonvalidity/draw_dispatch_indirect_common.txt[]
|
|
include::{chapters}/commonvalidity/draw_indirect_drawcount.txt[]
|
|
* [[VUID-vkCmdDrawIndirect-firstInstance-00478]]
|
|
If the <<features-drawIndirectFirstInstance,drawIndirectFirstInstance>>
|
|
feature is not enabled, all the pname:firstInstance members of the
|
|
sname:VkDrawIndirectCommand structures accessed by this command must: be
|
|
code:0
|
|
* [[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.txt[]
|
|
--
|
|
|
|
[open,refpage='VkDrawIndirectCommand',desc='Structure specifying a draw indirect command',type='structs',xrefs='vkCmdDrawIndirect']
|
|
--
|
|
|
|
The sname:VkDrawIndirectCommand structure is defined as:
|
|
|
|
include::{generated}/api/structs/VkDrawIndirectCommand.txt[]
|
|
|
|
* 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,drawIndirectFirstInstance>>
|
|
feature is not enabled, pname:firstInstance must: be code:0
|
|
****
|
|
|
|
include::{generated}/validity/structs/VkDrawIndirectCommand.txt[]
|
|
|
|
--
|
|
|
|
ifdef::VK_KHR_draw_indirect_count[]
|
|
[open,refpage='vkCmdDrawIndirectCountKHR',desc='Perform an indirect draw with the draw count sourced from a buffer',type='protos']
|
|
--
|
|
:refpage: vkCmdDrawIndirectCountKHR
|
|
|
|
To record a non-indexed draw call with a draw call count sourced from a
|
|
buffer, call:
|
|
|
|
ifdef::VK_KHR_draw_indirect_count[]
|
|
include::{generated}/api/protos/vkCmdDrawIndirectCountKHR.txt[]
|
|
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.txt[]
|
|
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:vkCmdDrawIndirectCountKHR 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.txt[]
|
|
include::{chapters}/commonvalidity/draw_vertex_binding.txt[]
|
|
include::{chapters}/commonvalidity/draw_dispatch_indirect_common.txt[]
|
|
include::{chapters}/commonvalidity/draw_indirect_count_common.txt[]
|
|
* [[VUID-vkCmdDrawIndirectCountKHR-stride-03110]]
|
|
pname:stride must: be a multiple of `4` and must: be greater than or
|
|
equal to sizeof(sname:VkDrawIndirectCommand)
|
|
* [[VUID-vkCmdDrawIndirectCountKHR-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-vkCmdDrawIndirectCountKHR-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-vkCmdDrawIndirectCountKHR-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/vkCmdDrawIndirectCountKHR.txt[]
|
|
|
|
--
|
|
endif::VK_KHR_draw_indirect_count[]
|
|
|
|
[open,refpage='vkCmdDrawIndexedIndirect',desc='Perform an indexed indirect draw',type='protos']
|
|
--
|
|
:refpage: vkCmdDrawIndexedIndirect
|
|
|
|
To record an indexed indirect draw, call:
|
|
|
|
include::{generated}/api/protos/vkCmdDrawIndexedIndirect.txt[]
|
|
|
|
* 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.txt[]
|
|
include::{chapters}/commonvalidity/draw_vertex_binding.txt[]
|
|
include::{chapters}/commonvalidity/draw_dispatch_indirect_common.txt[]
|
|
include::{chapters}/commonvalidity/draw_indirect_drawcount.txt[]
|
|
* [[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-firstInstance-00530]]
|
|
If the <<features-drawIndirectFirstInstance,drawIndirectFirstInstance>>
|
|
feature is not enabled, all the pname:firstInstance members of the
|
|
sname:VkDrawIndexedIndirectCommand structures accessed by this command
|
|
must: be code:0
|
|
* [[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.txt[]
|
|
--
|
|
|
|
[open,refpage='VkDrawIndexedIndirectCommand',desc='Structure specifying a draw indexed indirect command',type='structs',xrefs='vkCmdDrawIndexedIndirect']
|
|
--
|
|
|
|
The sname:VkDrawIndexedIndirectCommand structure is defined as:
|
|
|
|
include::{generated}/api/structs/VkDrawIndexedIndirectCommand.txt[]
|
|
|
|
* 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
|
|
****
|
|
* [[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-indexSize-00553]]
|
|
[eq]#(code:indexSize * (pname:firstIndex {plus} pname:indexCount) {plus}
|
|
pname:offset)# must: be less than or equal to the size of the bound
|
|
index buffer, with code:indexSize being based on the type specified by
|
|
pname:indexType, where the index buffer, pname:indexType, and
|
|
pname:offset are specified via fname:vkCmdBindIndexBuffer
|
|
* [[VUID-VkDrawIndexedIndirectCommand-firstInstance-00554]]
|
|
If the <<features-drawIndirectFirstInstance,drawIndirectFirstInstance>>
|
|
feature is not enabled, pname:firstInstance must: be code:0
|
|
****
|
|
|
|
include::{generated}/validity/structs/VkDrawIndexedIndirectCommand.txt[]
|
|
|
|
--
|
|
|
|
ifdef::VK_KHR_draw_indirect_count[]
|
|
[open,refpage='vkCmdDrawIndexedIndirectCountKHR',desc='Perform an indexed indirect draw with the draw count sourced from a buffer',type='protos']
|
|
--
|
|
:refpage: vkCmdDrawIndexedIndirectCountKHR
|
|
|
|
To record an indexed draw call with a draw call count sourced from a buffer,
|
|
call:
|
|
|
|
ifdef::VK_KHR_draw_indirect_count[]
|
|
include::{generated}/api/protos/vkCmdDrawIndexedIndirectCountKHR.txt[]
|
|
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.txt[]
|
|
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:vkCmdDrawIndexedIndirectCountKHR 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.txt[]
|
|
include::{chapters}/commonvalidity/draw_vertex_binding.txt[]
|
|
include::{chapters}/commonvalidity/draw_dispatch_indirect_common.txt[]
|
|
include::{chapters}/commonvalidity/draw_indirect_count_common.txt[]
|
|
* [[VUID-vkCmdDrawIndexedIndirectCountKHR-stride-03142]]
|
|
pname:stride must: be a multiple of `4` and must: be greater than or
|
|
equal to sizeof(sname:VkDrawIndexedIndirectCommand)
|
|
* [[VUID-vkCmdDrawIndexedIndirectCountKHR-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-vkCmdDrawIndexedIndirectCountKHR-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-vkCmdDrawIndexedIndirectCountKHR-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/vkCmdDrawIndexedIndirectCountKHR.txt[]
|
|
|
|
--
|
|
endif::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 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.txt[]
|
|
|
|
* 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.txt[]
|
|
include::{chapters}/commonvalidity/draw_vertex_binding.txt[]
|
|
* [[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
|
|
slink:VkPhysicalDeviceLimits::pname:maxTransformFeedbackBufferDataStride
|
|
* [[VUID-vkCmdDrawIndirectByteCountEXT-counterBuffer-02290]]
|
|
pname:counterBuffer must: have been created with the
|
|
ename:VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set
|
|
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.txt[]
|
|
--
|
|
|
|
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,
|
|
inherited conditional rendering>> 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.txt[]
|
|
|
|
* pname:commandBuffer is the command buffer into which this command will
|
|
be recorded.
|
|
* pname:pConditionalRenderingBegin is a pointer to an instance of the
|
|
slink:VkConditionalRenderingBeginInfoEXT structure specifying the
|
|
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.txt[]
|
|
--
|
|
|
|
[open,refpage='VkConditionalRenderingBeginInfoEXT',desc='Structure specifying conditional rendering begin info',type='structs']
|
|
--
|
|
|
|
The sname:VkConditionalRenderingBeginInfoEXT structure is defined as:
|
|
|
|
include::{generated}/api/structs/VkConditionalRenderingBeginInfoEXT.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific 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.txt[]
|
|
|
|
--
|
|
|
|
[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.txt[]
|
|
|
|
* 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.txt[]
|
|
|
|
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.txt[]
|
|
|
|
* 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.txt[]
|
|
--
|
|
|
|
endif::VK_EXT_conditional_rendering[]
|
|
|
|
ifdef::VK_NV_mesh_shader[]
|
|
include::VK_NV_mesh_shader/drawing.txt[]
|
|
endif::VK_NV_mesh_shader[]
|