• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2015-2018 Khronos Group. This work is licensed under a
2// Creative Commons Attribution 4.0 International License; see
3// http://creativecommons.org/licenses/by/4.0/
4
5[[vertexpostproc]]
6= Fixed-Function Vertex Post-Processing
7
8After programmable vertex processing, the following fixed-function
9operations are applied to vertices of the resulting primitives:
10
11ifdef::VK_NV_viewport_swizzle[]
12  * Viewport swizzle (see <<vertexpostproc-viewport-swizzle,Viewport
13    Swizzle>>)
14endif::VK_NV_viewport_swizzle[]
15  * Flat shading (see <<vertexpostproc-flatshading>>).
16  * Primitive clipping, including client-defined half-spaces (see
17    <<vertexpostproc-clipping,Primitive Clipping>>).
18  * Shader output attribute clipping (see
19    <<vertexpostproc-clipping-shader-outputs,Clipping Shader Outputs>>).
20ifdef::VK_NV_clip_space_w_scaling[]
21  * Clip space W scaling (see <<vertexpostproc-viewportwscaling,Controlling
22    Viewport W Scaling>>).
23endif::VK_NV_clip_space_w_scaling[]
24  * Perspective division on clip coordinates (see
25    <<vertexpostproc-coord-transform,Coordinate Transformations>>).
26  * Viewport mapping, including depth range scaling (see
27    <<vertexpostproc-viewport,Controlling the Viewport>>).
28  * Front face determination for polygon primitives (see
29    <<primsrast-polygons-basic,Basic Polygon Rasterization>>).
30
31ifdef::editing-notes[]
32[NOTE]
33.editing-note
34====
35TODO:Odd that this one link to a different chapter is in this list.
36====
37endif::editing-notes[]
38
39Next, rasterization is performed on primitives as described in chapter
40<<primsrast,Rasterization>>.
41
42ifdef::VK_NV_viewport_swizzle[]
43[[vertexpostproc-viewport-swizzle]]
44== Viewport Swizzle
45
46[open,refpage='VkPipelineViewportSwizzleStateCreateInfoNV',desc='Structure specifying swizzle applied to primitive clip coordinates',type='structs']
47--
48
49Each primitive sent to a given viewport has a swizzle and optional: negation
50applied to its clip coordinates.
51The swizzle that is applied depends on the viewport index, and is controlled
52by the sname:VkPipelineViewportSwizzleStateCreateInfoNV pipeline state:
53
54include::../api/structs/VkPipelineViewportSwizzleStateCreateInfoNV.txt[]
55
56  * pname:sType is the type of this structure.
57  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
58  * pname:flags is reserved for future use.
59  * pname:viewportCount is the number of viewport swizzles used by the
60    pipeline.
61  * pname:pViewportSwizzles is a pointer to an array of
62    slink:VkViewportSwizzleNV structures, defining the viewport swizzles.
63
64.Valid Usage
65****
66  * [[VUID-VkPipelineViewportSwizzleStateCreateInfoNV-viewportCount-01215]]
67    pname:viewportCount must: match the pname:viewportCount set in
68    sname:VkPipelineViewportStateCreateInfo
69****
70
71include::../validity/structs/VkPipelineViewportSwizzleStateCreateInfoNV.txt[]
72--
73
74[open,refpage='VkPipelineViewportSwizzleStateCreateFlagsNV',desc='Reserved for future use',type='enums']
75--
76include::../api/flags/VkPipelineViewportSwizzleStateCreateFlagsNV.txt[]
77
78sname:VkPipelineViewportSwizzleStateCreateFlagsNV is a bitmask type for
79setting a mask, but is currently reserved for future use.
80--
81
82The sname:VkPipelineViewportSwizzleStateCreateInfoNV state is set by adding
83an instance of this structure to the pname:pNext chain of an instance of the
84sname:VkPipelineViewportStateCreateInfo structure and setting the graphics
85pipeline state with flink:vkCreateGraphicsPipelines.
86
87Each viewport specified from 0 to pname:viewportCount - 1 has its x,y,z,w
88swizzle state set to the corresponding pname:x, pname:y, pname:z and pname:w
89in the slink:VkViewportSwizzleNV structure.
90Each component is of type elink:VkViewportCoordinateSwizzleNV, which
91determines the type of swizzle for that component.
92The value of pname:x computes the new x component of the position as:
93
94[source,c]
95---------------------------------------------------
96if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV) x' = x;
97if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV) x' = -x;
98if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV) x' = y;
99if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV) x' = -y;
100if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV) x' = z;
101if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV) x' = -z;
102if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV) x' = w;
103if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV) x' = -w;
104---------------------------------------------------
105
106Similar selections are performed for the pname:y, pname:z, and pname:w
107coordinates.
108This swizzling is applied before clipping and perspective divide.
109If the swizzle for an active viewport index is not specified, the swizzle
110for pname:x is ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, pname:y
111is ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV, pname:z is
112ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV and pname:w is
113ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV.
114
115Viewport swizzle parameters are specified by setting the pname:pNext pointer
116of sname:VkGraphicsPipelineCreateInfo to point to an instance of
117sname:VkPipelineViewportSwizzleStateCreateInfoNV.
118slink:VkPipelineViewportSwizzleStateCreateInfoNV uses
119sname:VkViewportSwizzleNV to set the viewport swizzle parameters.
120
121[open,refpage='VkViewportSwizzleNV',desc='Structure specifying a viewport swizzle',type='structs']
122--
123
124The sname:VkViewportSwizzleNV structure is defined as:
125
126include::../api/structs/VkViewportSwizzleNV.txt[]
127
128  * pname:x is a elink:VkViewportCoordinateSwizzleNV value specifying the
129    swizzle operation to apply to the x component of the primitive
130  * pname:y is a elink:VkViewportCoordinateSwizzleNV value specifying the
131    swizzle operation to apply to the y component of the primitive
132  * pname:z is a elink:VkViewportCoordinateSwizzleNV value specifying the
133    swizzle operation to apply to the z component of the primitive
134  * pname:w is a elink:VkViewportCoordinateSwizzleNV value specifying the
135    swizzle operation to apply to the w component of the primitive
136
137include::../validity/structs/VkViewportSwizzleNV.txt[]
138--
139
140[open,refpage='VkViewportCoordinateSwizzleNV',desc='Specify how a viewport coordinate is swizzled',type='enums']
141--
142
143Possible values of the elink:VkViewportSwizzleNV::pname:x, pname:y, pname:z,
144and pname:w members, specifying swizzling of the corresponding components of
145primitives, are:
146
147include::../api/enums/VkViewportCoordinateSwizzleNV.txt[]
148
149These values are described in detail in <<vertexpostproc-viewport-swizzle,
150Viewport Swizzle>>.
151
152--
153
154endif::VK_NV_viewport_swizzle[]
155
156[[vertexpostproc-flatshading]]
157== Flat Shading
158
159_Flat shading_ a vertex output attribute means to assign all vertices of the
160primitive the same value for that output.
161
162The output values assigned are those of the _provoking vertex_ of the
163primitive.
164The provoking vertex depends on the primitive topology, and is generally the
165"`first`" vertex of the primitive.
166For primitives not processed by tessellation or geometry shaders, the
167provoking vertex is selected from the input vertices according to the
168following table.
169
170<<<
171
172[[provoking-vertex-selection]]
173.Provoking vertex selection
174[align="center",cols="75%,25%"]
175|====
176| Primitive type of primitive [eq]#i#                       | Provoking vertex number
177| ename:VK_PRIMITIVE_TOPOLOGY_POINT_LIST                    | [eq]#i#
178| ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST                     | [eq]#2 i#
179| ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP                    | [eq]#i#
180| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST                 | [eq]#3 i#
181| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP                | [eq]#i#
182| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN                  | [eq]#i {plus} 1#
183| ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY      | [eq]#4 i {plus} 1#
184| ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY     | [eq]#i {plus} 1#
185| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY  | [eq]#6 i#
186| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY | [eq]#2 i#
187|====
188
189.Caption
190****
191The <<provoking-vertex-selection,Provoking vertex selection>> table defines
192the output values used for flat shading the i^th^ primitive generated by
193drawing commands with the indicated primitive type, derived from the
194corresponding values of the vertex whose index is shown in the table.
195Primitives and vertices are numbered starting from zero.
196****
197
198Flat shading is applied to those vertex attributes that
199<<interfaces-iointerfaces-matching,match>> fragment input attributes which
200are decorated as code:Flat.
201
202If a geometry shader is active, the output primitive topology is either
203points, line strips, or triangle strips, and the selection of the provoking
204vertex behaves according to the corresponding row of the table.
205If a tessellation evaluation shader is active and a geometry shader is not
206active, the provoking vertex is undefined but must: be one of the vertices
207of the primitive.
208
209
210[[vertexpostproc-clipping]]
211== Primitive Clipping
212
213Primitives are culled against the _cull volume_ and then clipped to the
214_clip volume_.
215In clip coordinates, the _view volume_ is defined by:
216
217[latexmath]
218++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
219\begin{array}{c}
220-w_c \leq x_c \leq w_c \\
221-w_c \leq y_c \leq w_c \\
2220 \leq z_c \leq w_c
223\end{array}
224++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
225
226This view volume can: be further restricted by as many as
227sname:VkPhysicalDeviceLimits::pname:maxClipDistances client-defined
228half-spaces.
229
230The cull volume is the intersection of up to
231sname:VkPhysicalDeviceLimits::pname:maxCullDistances client-defined
232half-spaces (if no client-defined cull half-spaces are enabled, culling
233against the cull volume is skipped).
234
235A shader must: write a single cull distance for each enabled cull half-space
236to elements of the code:CullDistance array.
237If the cull distance for any enabled cull half-space is negative for all of
238the vertices of the primitive under consideration, the primitive is
239discarded.
240Otherwise the primitive is clipped against the clip volume as defined below.
241
242The clip volume is the intersection of up to
243sname:VkPhysicalDeviceLimits::pname:maxClipDistances client-defined
244half-spaces with the view volume (if no client-defined clip half-spaces are
245enabled, the clip volume is the view volume).
246
247A shader must: write a single clip distance for each enabled clip half-space
248to elements of the code:ClipDistance array.
249Clip half-space [eq]#i# is then given by the set of points satisfying the
250inequality
251
252  :: [eq]#c~i~(**P**) {geq} 0#
253
254where [eq]#c~i~(**P**)# is the clip distance [eq]#i# at point [eq]#**P**#.
255For point primitives, [eq]#c~i~(**P**)# is simply the clip distance for the
256vertex in question.
257For line and triangle primitives, per-vertex clip distances are interpolated
258using a weighted mean, with weights derived according to the algorithms
259described in sections <<primsrast-lines-basic,Basic Line Segment
260Rasterization>> and <<primsrast-polygons-basic,Basic Polygon
261Rasterization>>, using the perspective interpolation equations.
262
263The number of client-defined clip and cull half-spaces that are enabled is
264determined by the explicit size of the built-in arrays code:ClipDistance and
265code:CullDistance, respectively, declared as an output in the interface of
266the entry point of the final shader stage before clipping.
267
268Depth clamping is enabled or disabled via the pname:depthClampEnable enable
269of the sname:VkPipelineRasterizationStateCreateInfo structure.
270If depth clamping is enabled, the plane equation
271
272  :: [eq]#0 {leq} z~c~ {leq} w~c~#
273
274(see the clip volume definition above) is ignored by view volume clipping
275(effectively, there is no near or far plane clipping).
276
277If the primitive under consideration is a point or line segment, then
278clipping passes it unchanged if its vertices lie entirely within the clip
279volume.
280
281ifndef::VK_VERSION_1_1,VK_KHR_maintenance2[]
282If a point's vertex lies outside of the clip volume, the entire primitive
283may: be discarded.
284endif::VK_VERSION_1_1,VK_KHR_maintenance2[]
285
286ifdef::VK_VERSION_1_1,VK_KHR_maintenance2[]
287
288[open,refpage='VkPointClippingBehavior',desc='Enum specifying the point clipping behaviour',type='enums']
289--
290
291Possible values of
292slink:VkPhysicalDevicePointClippingProperties::pname:pointClippingBehavior,
293specifying clipping behavior of a point primitive whose vertex lies outside
294the clip volume, are:
295
296include::../api/enums/VkPointClippingBehavior.txt[]
297
298ifdef::VK_KHR_maintenance2[]
299or the equivalent
300
301include::../api/enums/VkPointClippingBehaviorKHR.txt[]
302endif::VK_KHR_maintenance2[]
303
304  * ename:VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES specifies that the
305    primitive is discarded if the vertex lies outside any clip plane,
306    including the planes bounding the view volume.
307  * ename:VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY specifies that
308    the primitive is discarded only if the vertex lies outside any user clip
309    plane.
310
311--
312
313endif::VK_VERSION_1_1,VK_KHR_maintenance2[]
314
315If either of a line segment's vertices lie outside of the clip volume, the
316line segment may: be clipped, with new vertex coordinates computed for each
317vertex that lies outside the clip volume.
318A clipped line segment endpoint lies on both the original line segment and
319the boundary of the clip volume.
320
321This clipping produces a value, [eq]#0 {leq} t {leq} 1#, for each clipped
322vertex.
323If the coordinates of a clipped vertex are [eq]#**P**# and the original
324vertices`' coordinates are [eq]#**P**~1~# and [eq]#**P**~2~#, then [eq]#t#
325is given by
326
327  :: [eq]#**P** = t **P**~1~ {plus} (1-t) **P**~2~#.
328
329ifdef::editing-notes[]
330[NOTE]
331.editing-note
332====
333This is weird - it gives **P**, not t.
334====
335endif::editing-notes[]
336
337[eq]#t# is used to clip vertex output attributes as described in
338<<vertexpostproc-clipping-shader-outputs,Clipping Shader Outputs>>.
339
340If the primitive is a polygon, it passes unchanged if every one of its edges
341lie entirely inside the clip volume, and it is discarded if every one of its
342edges lie entirely outside the clip volume.
343If the edges of the polygon intersect the boundary of the clip volume, the
344intersecting edges are reconnected by new edges that lie along the boundary
345of the clip volume - in some cases requiring the introduction of new
346vertices into a polygon.
347
348If a polygon intersects an edge of the clip volume's boundary, the clipped
349polygon must: include a point on this boundary edge.
350
351Primitives rendered with user-defined half-spaces must: satisfy a
352complementarity criterion.
353Suppose a series of primitives is drawn where each vertex [eq]#i# has a
354single specified clip distance [eq]#d~i~# (or a number of similarly
355specified clip distances, if multiple half-spaces are enabled).
356Next, suppose that the same series of primitives are drawn again with each
357such clip distance replaced by [eq]#-d~i~# (and the graphics pipeline is
358otherwise the same).
359In this case, primitives must: not be missing any pixels, and pixels must:
360not be drawn twice in regions where those primitives are cut by the clip
361planes.
362
363
364[[vertexpostproc-clipping-shader-outputs]]
365== Clipping Shader Outputs
366
367Next, vertex output attributes are clipped.
368The output values associated with a vertex that lies within the clip volume
369are unaffected by clipping.
370If a primitive is clipped, however, the output values assigned to vertices
371produced by clipping are clipped.
372
373Let the output values assigned to the two vertices [eq]#**P**~1~# and
374[eq]#**P**~2~# of an unclipped edge be [eq]#**c**~1~# and [eq]#**c**~2~#.
375The value of [eq]#t# (see <<vertexpostproc-clipping,Primitive Clipping>>)
376for a clipped point [eq]#**P**# is used to obtain the output value
377associated with [eq]#**P**# as
378
379  :: [eq]#**c** = t **c**~1~ {plus} (1-t) **c**~2~#.
380
381(Multiplying an output value by a scalar means multiplying each of _x_, _y_,
382_z_, and _w_ by the scalar.)
383
384Since this computation is performed in clip space before division by
385[eq]#w~c~#, clipped output values are perspective-correct.
386
387Polygon clipping creates a clipped vertex along an edge of the clip volume's
388boundary.
389This situation is handled by noting that polygon clipping proceeds by
390clipping against one half-space at a time.
391Output value clipping is done in the same way, so that clipped points always
392occur at the intersection of polygon edges (possibly already clipped) with
393the clip volume's boundary.
394
395For vertex output attributes whose matching fragment input attributes are
396decorated with code:NoPerspective, the value of [eq]#t# used to obtain the
397output value associated with [eq]#**P**# will be adjusted to produce results
398that vary linearly in framebuffer space.
399
400Output attributes of integer or unsigned integer type must: always be flat
401shaded.
402Flat shaded attributes are constant over the primitive being rasterized (see
403<<primsrast-lines-basic,Basic Line Segment Rasterization>> and
404<<primsrast-polygons-basic,Basic Polygon Rasterization>>), and no
405interpolation is performed.
406The output value [eq]#**c**# is taken from either [eq]#**c**~1~# or
407[eq]#**c**~2~#, since flat shading has already occurred and the two values
408are identical.
409
410ifdef::VK_NV_clip_space_w_scaling[]
411include::VK_NV_clip_space_w_scaling/vertexpostproc.txt[]
412endif::VK_NV_clip_space_w_scaling[]
413
414[[vertexpostproc-coord-transform]]
415== Coordinate Transformations
416
417_Clip coordinates_ for a vertex result from shader execution, which yields a
418vertex coordinate code:Position.
419
420Perspective division on clip coordinates yields _normalized device
421coordinates_, followed by a _viewport_ transformation (see
422<<vertexpostproc-viewport,Controlling the Viewport>>) to convert these
423coordinates into _framebuffer coordinates_.
424
425If a vertex in clip coordinates has a position given by
426
427[latexmath]
428++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
429\left(\begin{array}{c}
430x_c \\
431y_c \\
432z_c \\
433w_c
434\end{array}\right)
435++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
436
437then the vertex's normalized device coordinates are
438[latexmath]
439++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
440\left(
441        \begin{array}{c}
442                x_d \\
443                y_d \\
444                z_d
445        \end{array}
446\right) =
447\left(
448        \begin{array}{c}
449                \frac{x_c}{w_c} \\
450                \frac{y_c}{w_c} \\
451                \frac{z_c}{w_c}
452        \end{array}
453\right)
454++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
455
456
457[[vertexpostproc-viewport]]
458== Controlling the Viewport
459
460The viewport transformation is determined by the selected viewport's width
461and height in pixels, [eq]#p~x~# and [eq]#p~y~#, respectively, and its
462center [eq]#(o~x~, o~y~)# (also in pixels), as well as its depth range min
463and max determining a depth range scale value [eq]#p~z~# and a depth range
464bias value [eq]#o~z~# (defined below).
465The vertex's framebuffer coordinates [eq]#(x~f~, y~f~, z~f~)# are given by
466
467  :: [eq]#x~f~ = (p~x~ / 2) x~d~ {plus} o~x~#
468  :: [eq]#y~f~ = (p~y~ / 2) y~d~ {plus} o~y~#
469  :: [eq]#z~f~ = p~z~ {times} z~d~ {plus} o~z~#
470
471Multiple viewports are available, numbered zero up to
472sname:VkPhysicalDeviceLimits::pname:maxViewports minus one.
473The number of viewports used by a pipeline is controlled by the
474pname:viewportCount member of the sname:VkPipelineViewportStateCreateInfo
475structure used in pipeline creation.
476
477[open,refpage='VkPipelineViewportStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline viewport state',type='structs']
478--
479
480The sname:VkPipelineViewportStateCreateInfo structure is defined as:
481
482include::../api/structs/VkPipelineViewportStateCreateInfo.txt[]
483
484  * pname:sType is the type of this structure.
485  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
486  * pname:flags is reserved for future use.
487  * pname:viewportCount is the number of viewports used by the pipeline.
488  * pname:pViewports is a pointer to an array of slink:VkViewport
489    structures, defining the viewport transforms.
490    If the viewport state is dynamic, this member is ignored.
491  * pname:scissorCount is the number of <<fragops-scissor,scissors>> and
492    must: match the number of viewports.
493  * pname:pScissors is a pointer to an array of slink:VkRect2D structures
494    which define the rectangular bounds of the scissor for the corresponding
495    viewport.
496    If the scissor state is dynamic, this member is ignored.
497
498.Valid Usage
499****
500  * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216]]
501    If the <<features-features-multiViewport,multiple viewports>> feature is
502    not enabled, pname:viewportCount must: be `1`
503  * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217]]
504    If the <<features-features-multiViewport,multiple viewports>> feature is
505    not enabled, pname:scissorCount must: be `1`
506  * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218]]
507    pname:viewportCount must: be between `1` and
508    sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive
509  * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219]]
510    pname:scissorCount must: be between `1` and
511    sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive
512  * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220]]
513    pname:scissorCount and pname:viewportCount must: be identical
514ifdef::VK_NV_clip_space_w_scaling[]
515  * [[VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726]]
516    If the pname:viewportWScalingEnable member of a
517    slink:VkPipelineViewportWScalingStateCreateInfoNV structure chained to
518    the pname:pNext chain is ename:VK_TRUE, the pname:viewportCount member
519    of the slink:VkPipelineViewportWScalingStateCreateInfoNV structure must:
520    be equal to pname:viewportCount
521endif::VK_NV_clip_space_w_scaling[]
522****
523
524include::../validity/structs/VkPipelineViewportStateCreateInfo.txt[]
525--
526
527[open,refpage='VkPipelineViewportStateCreateFlags',desc='Reserved for future use',type='enums']
528--
529include::../api/flags/VkPipelineViewportStateCreateFlags.txt[]
530
531sname:VkPipelineViewportStateCreateFlags is a bitmask type for setting a
532mask, but is currently reserved for future use.
533--
534
535ifndef::VK_NV_viewport_array2+VK_EXT_shader_viewport_index_layer[]
536If a geometry shader is active and has an output variable decorated with
537code:ViewportIndex, the viewport transformation uses the viewport
538corresponding to the value assigned to code:ViewportIndex taken from an
539implementation-dependent vertex of each primitive.
540If code:ViewportIndex is outside the range zero to pname:viewportCount minus
541one for a primitive, or if the geometry shader did not assign a value to
542code:ViewportIndex for all vertices of a primitive due to flow control, the
543results of the viewport transformation of the vertices of such primitives
544are undefined.
545If no geometry shader is active, or if the geometry shader does not have an
546output decorated with code:ViewportIndex, the viewport numbered zero is used
547by the viewport transformation.
548endif::VK_NV_viewport_array2+VK_EXT_shader_viewport_index_layer[]
549
550ifdef::VK_NV_viewport_array2,VK_EXT_shader_viewport_index_layer[]
551ifdef::VK_NV_viewport_array2[]
552A _vertex processing stage_ may direct each primitive to zero or more
553viewports.
554The destination viewports for a primitive are selected by the last active
555vertex processing stage that has an output variable decorated with
556code:ViewportIndex (selecting a single viewport) or code:ViewportMaskNV
557(selecting multiple viewports).
558The viewport transform uses the viewport corresponding to either the value
559assigned to code:ViewportIndex or one of the bits set in
560code:ViewportMaskNV, and taken from an implementation-dependent vertex of
561each primitive.
562If code:ViewportIndex or any of the bits in code:ViewportMaskNV are outside
563the range zero to pname:viewportCount minus one for a primitive, or if the
564last active vertex processing stage did not assign a value to either
565code:ViewportIndex or code:ViewportMaskNV for all vertices of a primitive
566due to flow control, the results of the viewport transformation of the
567vertices of such primitives are undefined.
568If the last vertex processing stage does not have an output decorated with
569code:ViewportIndex or code:ViewportMaskNV, the viewport numbered zero is
570used by the viewport transformation.
571endif::VK_NV_viewport_array2[]
572ifndef::VK_NV_viewport_array2[]
573ifdef::VK_EXT_shader_viewport_index_layer[]
574A _vertex processing stage_ can: direct each primitive to one of several
575viewports.
576The destination viewport for a primitive is selected by the last active
577vertex processing stage that has an output variable decorated with
578code:ViewportIndex.
579The viewport transform uses the viewport corresponding to the value assigned
580to code:ViewportIndex taken from an implementation-dependent vertex of each
581primitive.
582If code:ViewportIndex is outside the range zero to pname:viewportCount minus
583one for a primitive, or if the last active vertex processing stage did not
584assign a value to code:ViewportIndex for all vertices of a primitive due to
585flow control, the results of the viewport transformation of the vertices of
586such primitives are undefined.
587If the last vertex processing stage does not have an output decorated with
588code:ViewportIndex, the viewport numbered zero is used by the viewport
589transformation.
590endif::VK_EXT_shader_viewport_index_layer[]
591endif::VK_NV_viewport_array2[]
592endif::VK_NV_viewport_array2,VK_EXT_shader_viewport_index_layer[]
593
594A single vertex can: be used in more than one individual primitive, in
595primitives such as ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP.
596In this case, the viewport transformation is applied separately for each
597primitive.
598
599[open,refpage='vkCmdSetViewport',desc='Set the viewport on a command buffer',type='protos']
600--
601
602If the bound pipeline state object was not created with the
603ename:VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled, viewport
604transformation parameters are specified using the pname:pViewports member of
605sname:VkPipelineViewportStateCreateInfo in the pipeline state object.
606If the pipeline state object was created with the
607ename:VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled, the viewport
608transformation parameters are dynamically set and changed with the command:
609
610include::../api/protos/vkCmdSetViewport.txt[]
611
612  * pname:commandBuffer is the command buffer into which the command will be
613    recorded.
614  * pname:firstViewport is the index of the first viewport whose parameters
615    are updated by the command.
616  * pname:viewportCount is the number of viewports whose parameters are
617    updated by the command.
618  * pname:pViewports is a pointer to an array of slink:VkViewport structures
619    specifying viewport parameters.
620
621The viewport parameters taken from element [eq]#i# of pname:pViewports
622replace the current state for the viewport index [eq]#pname:firstViewport
623{plus} i#, for [eq]#i# in [eq]#[0, pname:viewportCount)#.
624
625.Valid Usage
626****
627  * [[VUID-vkCmdSetViewport-None-01221]]
628    The bound graphics pipeline must: have been created with the
629    ename:VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled
630  * [[VUID-vkCmdSetViewport-firstViewport-01222]]
631    pname:firstViewport must: be less than
632    sname:VkPhysicalDeviceLimits::pname:maxViewports
633  * [[VUID-vkCmdSetViewport-firstViewport-01223]]
634    The sum of pname:firstViewport and pname:viewportCount must: be between
635    `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive
636  * [[VUID-vkCmdSetViewport-firstViewport-01224]]
637    If the <<features-features-multiViewport,multiple viewports>> feature is
638    not enabled, pname:firstViewport must: be `0`
639  * [[VUID-vkCmdSetViewport-viewportCount-01225]]
640    If the <<features-features-multiViewport,multiple viewports>> feature is
641    not enabled, pname:viewportCount must: be `1`
642****
643
644include::../validity/protos/vkCmdSetViewport.txt[]
645--
646
647Both slink:VkPipelineViewportStateCreateInfo and flink:vkCmdSetViewport use
648sname:VkViewport to set the viewport transformation parameters.
649
650[open,refpage='VkViewport',desc='Structure specifying a viewport',type='structs']
651--
652
653The sname:VkViewport structure is defined as:
654
655include::../api/structs/VkViewport.txt[]
656
657  * pname:x and pname:y are the viewport's upper left corner [eq]#(x,y)#.
658  * pname:width and pname:height are the viewport's width and height,
659    respectively.
660  * pname:minDepth and pname:maxDepth are the depth range for the viewport.
661    It is valid for pname:minDepth to be greater than or equal to
662    pname:maxDepth.
663
664The framebuffer depth coordinate [eq]#pname:z~f~# may: be represented using
665either a fixed-point or floating-point representation.
666However, a floating-point representation must: be used if the depth/stencil
667attachment has a floating-point depth component.
668If an [eq]#m#-bit fixed-point representation is used, we assume that it
669represents each value latexmath:[\frac{k}{2^m - 1}], where [eq]#k {elem} {
6700, 1, ..., 2^m^-1 }#, as [eq]#k# (e.g. 1.0 is represented in binary as a
671string of all ones).
672
673The viewport parameters shown in the above equations are found from these
674values as
675
676  :: [eq]#o~x~ = pname:x {plus} pname:width / 2#
677  :: [eq]#o~y~ = pname:y {plus} pname:height / 2#
678  :: [eq]#o~z~ = pname:minDepth#
679  :: [eq]#p~x~ = pname:width#
680  :: [eq]#p~y~ = pname:height#
681  :: [eq]#p~z~ = pname:maxDepth - pname:minDepth#.
682
683ifdef::VK_VERSION_1_1,VK_KHR_maintenance1[]
684The application can: specify a negative term for pname:height, which has the
685effect of negating the y coordinate in clip space before performing the
686transform.
687When using a negative pname:height, the application should: also adjust the
688pname:y value to point to the lower left corner of the viewport instead of
689the upper left corner.
690Using the negative pname:height allows the application to avoid having to
691negate the y component of the code:Position output from the last vertex
692processing stage in shaders that also target other graphics APIs.
693endif::VK_VERSION_1_1,VK_KHR_maintenance1[]
694
695The width and height of the <<features-limits-maxViewportDimensions,
696implementation-dependent maximum viewport dimensions>> must: be greater than
697or equal to the width and height of the largest image which can: be created
698and attached to a framebuffer.
699
700The floating-point viewport bounds are represented with an
701<<features-limits-viewportSubPixelBits,implementation-dependent precision>>.
702
703.Valid Usage
704****
705  * [[VUID-VkViewport-width-01770]]
706    pname:width must: be greater than `0.0`
707  * [[VUID-VkViewport-width-01771]]
708    pname:width must: be less than or equal to
709    sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[0]
710ifndef::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[]
711  * [[VUID-VkViewport-height-01772]]
712    pname:height must: be greater than `0.0`
713endif::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[]
714  * [[VUID-VkViewport-height-01773]]
715    The absolute value of pname:height must: be less than or equal to
716    sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[1]
717  * [[VUID-VkViewport-x-01774]]
718    pname:x must: be greater than or equal to pname:viewportBoundsRange[0]
719  * [[VUID-VkViewport-x-01232]]
720    [eq]#(pname:x {plus} pname:width)# must: be less than or equal to
721    pname:viewportBoundsRange[1]
722  * [[VUID-VkViewport-y-01775]]
723    pname:y must: be greater than or equal to pname:viewportBoundsRange[0]
724ifdef::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[]
725  * [[VUID-VkViewport-y-01776]]
726    pname:y must: be less than or equal to pname:viewportBoundsRange[1]
727  * [[VUID-VkViewport-y-01777]]
728    [eq]#(pname:y {plus} pname:height)# must: be greater than or equal to
729    pname:viewportBoundsRange[0]
730endif::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[]
731  * [[VUID-VkViewport-y-01233]]
732    [eq]#(pname:y {plus} pname:height)# must: be less than or equal to
733    pname:viewportBoundsRange[1]
734ifdef::VK_EXT_depth_range_unrestricted[]
735  * [[VUID-VkViewport-minDepth-01234]]
736    Unless `<<VK_EXT_depth_range_unrestricted>>` extension is enabled
737    pname:minDepth must: be between `0.0` and `1.0`, inclusive
738endif::VK_EXT_depth_range_unrestricted[]
739ifndef::VK_EXT_depth_range_unrestricted[]
740  * [[VUID-VkViewport-minDepth-01234]]
741    pname:minDepth must: be between `0.0` and `1.0`, inclusive
742endif::VK_EXT_depth_range_unrestricted[]
743ifdef::VK_EXT_depth_range_unrestricted[]
744  * [[VUID-VkViewport-maxDepth-01235]]
745    Unless `<<VK_EXT_depth_range_unrestricted>>` extension is enabled
746    pname:maxDepth must: be between `0.0` and `1.0`, inclusive
747endif::VK_EXT_depth_range_unrestricted[]
748ifndef::VK_EXT_depth_range_unrestricted[]
749  * [[VUID-VkViewport-maxDepth-01235]]
750    pname:maxDepth must: be between `0.0` and `1.0`, inclusive
751endif::VK_EXT_depth_range_unrestricted[]
752****
753
754include::../validity/structs/VkViewport.txt[]
755--
756