19.1. 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. Supported topologies are defined by VkPrimitiveTopology and include:

typedef enum VkPrimitiveTopology {
VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0,
VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1,
VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2,
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3,
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4,
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5,
VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10,
} VkPrimitiveTopology;

Each primitive topology, and its construction from a list of vertices, is summarized below.

Note The terminology “the vertex i ” means “the vertex with index i in the ordered list of vertices defining this primitive”.

19.1.1. Points

A series of individual points are specified with topology VK_PRIMITIVE_TOPOLOGY_POINT_LIST. Each vertex defines a separate point.

19.1.2. Separate Lines

Individual line segments, each defined by a pair of vertices, are specified with topology VK_PRIMITIVE_TOPOLOGY_LINE_LIST. The first two vertices define the first segment, with subsequent pairs of vertices each defining one more segment. If the number of vertices is odd, then the last vertex is ignored.

19.1.3. Line Strips

A series of one or more connected line segments are specified with topology VK_PRIMITIVE_TOPOLOGY_LINE_STRIP. In this case, the first vertex specifies the first segment’s start point while the second vertex specifies the first segment’s endpoint and the second segment’s start point. In general, vertex i (for i > 0) specifies the beginning of the ith segment and the end of the previous segment. The last vertex specifies the end of the last segment. If only one vertex is specified, then no primitive is generated.

19.1.4. Triangle Strips

A triangle strip is a series of triangles connected along shared edges, and is specified with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP. In this case, the first three vertices define the first triangle, and their order is significant. Each subsequent vertex defines a new triangle using that point along with the last two vertices from the previous triangle, as shown in figure Figure 19.1, “Triangle strips, fans, and lists”. If fewer than three vertices are specified, no primitive is produced. The order of vertices in successive triangles changes as shown in the figure, so that all triangle faces have the same orientation.

19.1.5. Triangle Fans

A triangle fan is specified with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN. It is similar to a triangle strip, but changes the vertex replaced from the previous triangle as shown in figure Figure 19.1, “Triangle strips, fans, and lists”, so that all triangles in the fan share a common vertex.

19.1.6. Separate Triangles

Separate triangles are specified with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, as shown in figure Figure 19.1, “Triangle strips, fans, and lists”. In this case, vertices 3 i, 3 i + 1, and 3 i + 2 (in that order) determine a triangle for each i = 0, 1, …, n-1, where there are 3 n + k vertices drawn. k is either 0, 1, or 2; if k is not zero, the final k vertices are ignored.

Lines with adjacency are specified with topology VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, and are independent line segments where each endpoint has a corresponding adjacent vertex that is accessible in a geometry shader. If a geometry shader is not active, the adjacent vertices are ignored.

A line segment is drawn from vertex 4 i + 1 to vertex 4 i + 2 for each i = 0, 1, …, n-1, where there are 4 n + k vertices. k is either 0, 1, 2, or 3; if k is not zero, the final k vertices are ignored. For line segment i, vertices 4 i and 4 i + 3 vertices are considered adjacent to vertices 4 i + 1 and 4 i + 2, respectively, as shown in figure Figure 19.2, “Lines with adjacency”.

Line strips with adjacency are specified with topology VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY and are similar to line strips, except that each line segment has a pair of adjacent vertices that are accessible in a geometry shader. If a geometry shader is not active, the adjacent vertices are ignored.

A line segment is drawn from vertex i + 1 vertex to vertex i + 2 for each i = 0, 1, …, n-1, where there are n + 3 vertices. If there are fewer than four vertices, all vertices are ignored. For line segment i, vertices i and i + 3 are considered adjacent to vertices i + 1 and i + 2, respectively, as shown in figure Figure 19.2, “Lines with adjacency”.

Triangles with adjacency are specified with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, and are similar to separate triangles except that each triangle edge has an adjacent vertex that is accessible in a geometry shader. If a geometry shader is not active, the adjacent vertices are ignored.

Vertices 6 i, 6 i + 2, and 6 i + 4 (in that order) determine a triangle for each i = 0, 1, …, n-1, where there are 6 n+k vertices. k is either 0, 1, 2, 3, 4, or 5; if k is non-zero, the final k vertices are ignored. For triangle i, vertices 6 i + 1, 6 i + 3, and 6 i + 5 vertices are considered adjacent to edges from vertex 6 i to 6 i + 2, from 6 i + 2 to 6 i + 4, and from 6 i + 4 to 6 i vertices, respectively, as shown in figure Figure 19.3, “Triangles with adjacency”.

Triangle strips with adjacency are specified with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, and are similar to triangle strips except that each triangle edge has an adjacent vertex that is accessible in a geometry shader. If a geometry shader is not active, the adjacent vertices are ignored.

In triangle strips with adjacency, n triangles are drawn where there are 2 (n + 2) + k vertices. k is either 0 or 1; if k is 1, the final vertex is ignored. If there are fewer than 6 vertices, the entire primitive is ignored. Table Table 19.1, “Triangles generated by triangle strips with adjacency.” describes the vertices and order used to draw each triangle, and which vertices are considered adjacent to each edge of the triangle, as shown in figure Figure 19.4, “Triangle strips with adjacency”.

Table 19.1. Triangles generated by triangle strips with adjacency.

Primitive

1st

2nd

3rd

1/2

2/3

3/1

only (i = 0, n = 1)

0

2

4

1

5

3

first (i = 0)

0

2

4

1

6

3

middle (i odd)

2 i + 2

2 i

2 i + 4

2 i-2

2 i + 3

2 i + 6

middle (i even)

2 i

2 i + 2

2 i + 4

2 i-2

2 i + 6

2 i + 3

last (i=n-1, i odd)

2 i + 2

2 i

2 i + 4

2 i-2

2 i + 3

2 i + 5

last (i=n-1, i even)

2 i

2 i + 2

2 i + 4

2 i-2

2 i + 5

2 i + 3

19.1.11. Separate Patches

Separate patches are specified with topology VK_PRIMITIVE_TOPOLOGY_PATCH_LIST. A patch is an ordered collection of vertices used for primitive tessellation. The vertices comprising a patch have no implied geometric ordering, and are used by tessellation shaders and the fixed-function tessellator to generate new point, line, or triangle primitives.

Each patch in the series has a fixed number of vertices, specified by the patchControlPoints member of the VkPipelineTessellationStateCreateInfo structure passed to vkCreateGraphicsPipelines. Once assembled and vertex shaded, these patches are provided as input to the tessellation control shader stage.

If the number of vertices in a patch is given by v, vertices v × i through v × i + v - 1 (in that order) determine a patch for each i = 0, 1, …, n-1, where there are v × n + k vertices. k is in the range [0, v - 1]; if k is not zero, the final k vertices are ignored.

19.1.12. General Considerations For Polygon Primitives

Depending on the polygon mode, a polygon primitive generated from a drawing command with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, or VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY is rendered in one of several ways, such as outlining its border or filling its interior. The order of vertices in such a primitive is significant during polygon rasterization and fragment shading.