• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015-2022 The Khronos Group Inc.
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5[[vertexpostproc]]
6= Fixed-Function Vertex Post-Processing
7
8After <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization
9shader stages>>, the following fixed-function operations are applied to
10vertices of the resulting primitives:
11
12ifdef::VK_EXT_transform_feedback[]
13  * Transform feedback (see <<vertexpostproc-transform-feedback,Transform
14    Feedback>>)
15endif::VK_EXT_transform_feedback[]
16ifdef::VK_NV_viewport_swizzle[]
17  * Viewport swizzle (see <<vertexpostproc-viewport-swizzle,Viewport
18    Swizzle>>)
19endif::VK_NV_viewport_swizzle[]
20  * Flat shading (see <<vertexpostproc-flatshading>>).
21  * Primitive clipping, including client-defined half-spaces (see
22    <<vertexpostproc-clipping,Primitive Clipping>>).
23  * Shader output attribute clipping (see
24    <<vertexpostproc-clipping-shader-outputs,Clipping Shader Outputs>>).
25ifdef::VK_NV_clip_space_w_scaling[]
26  * Clip space W scaling (see <<vertexpostproc-viewportwscaling,Controlling
27    Viewport W Scaling>>).
28endif::VK_NV_clip_space_w_scaling[]
29  * Perspective division on clip coordinates (see
30    <<vertexpostproc-coord-transform,Coordinate Transformations>>).
31  * Viewport mapping, including depth range scaling (see
32    <<vertexpostproc-viewport,Controlling the Viewport>>).
33  * Front face determination for polygon primitives (see
34    <<primsrast-polygons-basic,Basic Polygon Rasterization>>).
35
36ifdef::editing-notes[]
37[NOTE]
38.editing-note
39====
40TODO:Odd that this one link to a different chapter is in this list.
41====
42endif::editing-notes[]
43
44Next, rasterization is performed on primitives as described in chapter
45<<primsrast,Rasterization>>.
46
47
48ifdef::VK_EXT_transform_feedback[]
49[[vertexpostproc-transform-feedback]]
50== Transform Feedback
51
52Before any other fixed-function vertex post-processing, vertex outputs from
53the last shader in the
54<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader
55stage>> can: be written out to one or more transform feedback buffers bound
56to the command buffer.
57To capture vertex outputs the last
58<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader
59stage>> shader must: be declared with the code:Xfb execution mode.
60Outputs decorated with code:XfbBuffer will be written out to the
61corresponding transform feedback buffers bound to the command buffer when
62transform feedback is active.
63Transform feedback buffers are bound to the command buffer by using
64flink:vkCmdBindTransformFeedbackBuffersEXT.
65Transform feedback is made active by calling
66flink:vkCmdBeginTransformFeedbackEXT and made inactive by calling
67flink:vkCmdEndTransformFeedbackEXT.
68After vertex data is written it is possible to use
69flink:vkCmdDrawIndirectByteCountEXT to start a new draw where the
70pname:vertexCount is derived from the number of bytes written by a previous
71transform feedback.
72
73When an individual point, line, or triangle primitive reaches the transform
74feedback stage while transform feedback is active, the values of the
75specified output variables are assembled into primitives and appended to the
76bound transform feedback buffers.
77After activating transform feedback, the values of the first assembled
78primitive are written at the starting offsets of the bound transform
79feedback buffers, and subsequent primitives are appended to the buffer.
80If the optional pname:pCounterBuffers and pname:pCounterBufferOffsets
81parameters are specified, the starting points within the transform feedback
82buffers are adjusted so data is appended to the previously written values
83indicated by the value stored by the implementation in the counter buffer.
84
85For multi-vertex primitives, all values for a given vertex are written
86before writing values for any other vertex.
87ifdef::VK_EXT_provoking_vertex[]
88When <<features-transformFeedbackPreservesProvokingVertex,
89pname:transformFeedbackPreservesProvokingVertex>> is not enabled,
90implementations
91endif::VK_EXT_provoking_vertex[]
92ifndef::VK_EXT_provoking_vertex[]
93Implementations
94endif::VK_EXT_provoking_vertex[]
95may: write out any vertex within the primitive first, but all subsequent
96vertices for that primitive must: be written out in a consistent winding
97order defined as follows:
98
99  * If neither <<geometry,geometry>> or <<tessellation,tessellation
100    shading>> is active, vertices within a primitive are appended according
101    to the winding order described by the <<drawing-primitive-topologies,
102    primitive topology>> defined by the
103    slink:VkPipelineInputAssemblyStateCreateInfo:pname:topology used to
104    execute the <<drawing,drawing command>>.
105  * If <<geometry,geometry shading>> is active, vertices within a primitive
106    are appended according to the winding order described by the
107    <<drawing-primitive-topologies, primitive topology>> defined by the
108    <<drawing-point-lists, code:OutputPoints>>, <<drawing-line-strips,
109    code:OutputLineStrips>>, or <<drawing-triangle-strips,
110    code:OutputTriangleStrips>> execution mode.
111  * If <<tessellation,tessellation shading>> is active but
112    <<geometry,geometry shading>> is not, vertices within a primitive are
113    appended according to the winding order defined by
114    <<tessellation-triangle-tessellation, triangle tessellation>>,
115    <<tessellation-quad-tessellation, quad tessellation>>, and
116    <<tessellation-isoline-tessellation, isoline tessellation>>.
117
118ifdef::VK_EXT_provoking_vertex[]
119When <<features-transformFeedbackPreservesProvokingVertex,
120pname:transformFeedbackPreservesProvokingVertex>> is enabled, then in
121addition to writing vertices with a consistent winding order, the vertex
122order must: preserve the <<vertexpostproc-flatshading, provoking vertex>> of
123each primitive:
124
125  * When the
126    <<VkPipelineRasterizationProvokingVertexStateCreateInfoEXT,pipeline's
127    provoking vertex mode>> is
128    ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the primitive's
129    provoking vertex must be the first vertex written.
130  * When the
131    <<VkPipelineRasterizationProvokingVertexStateCreateInfoEXT,pipeline's
132    provoking vertex mode>> is
133    ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the primitive's
134    provoking vertex must be the last vertex written.
135
136If <<limits-transformFeedbackPreservesTriangleFanProvokingVertex,
137pname:transformFeedbackPreservesTriangleFanProvokingVertex>> is
138ename:VK_FALSE, neither <<geometry, geometry>> nor <<tessellation,
139tessellation>> shading is active, and the <<drawing-primitive-topologies,
140primitive topology>> is ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, then the
141first vertex written from each primitive is implementation-defined even when
142<<features-transformFeedbackPreservesProvokingVertex,
143pname:transformFeedbackPreservesProvokingVertex>> is enabled.
144
145endif::VK_EXT_provoking_vertex[]
146
147When capturing vertices, the stride associated with each transform feedback
148buffer, as indicated by the code:XfbStride decoration, indicates the number
149of bytes of storage reserved for each vertex in the transform feedback
150buffer.
151For every vertex captured, each output attribute with a code:Offset
152decoration will be written to the storage reserved for the vertex at the
153associated transform feedback buffer.
154When writing output variables that are arrays or structures, individual
155array elements or structure members are written tightly packed in order.
156For vector types, individual components are written in order.
157For matrix types, outputs are written as an array of column vectors.
158
159If any component of an output with an assigned transform feedback offset was
160not written to by its shader, the value recorded for that component is
161undefined:.
162All components of an output variable must: be written at an offset aligned
163to the size of the component.
164The size of each component of an output variable must: be at least 32-bits.
165When capturing a vertex, any portion of the reserved storage not associated
166with an output variable with an assigned transform feedback offset will be
167unmodified.
168
169When transform feedback is inactive, no vertices are recorded.
170If there is a valid counter buffer handle and counter buffer offset in the
171pname:pCounterBuffers and pname:pCounterBufferOffsets arrays, writes to the
172corresponding transform feedback buffer will start at the byte offset
173represented by the value stored in the counter buffer location.
174
175Individual lines or triangles of a strip or fan primitive will be extracted
176and recorded separately.
177Incomplete primitives are not recorded.
178
179When using a geometry shader that emits vertices to multiple vertex streams,
180a primitive will be assembled and output for each stream when there are
181enough vertices emitted for the output primitive type.
182All outputs assigned to a given transform feedback buffer are required to
183come from a single vertex stream.
184
185The sizes of the transform feedback buffers are defined by the
186flink:vkCmdBindTransformFeedbackBuffersEXT pname:pSizes parameter for each
187of the bound buffers, or the size of the bound buffer, whichever is the
188lesser.
189If there is less space remaining in any of the transform feedback buffers
190than the size of all of the vertex data for that primitive based on the
191code:XfbStride for that code:XfbBuffer then no vertex data of that primitive
192is recorded in any transform feedback buffer, and the value for the number
193of primitives written in the corresponding
194ename:VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT query for all transform
195feedback buffers is no longer incremented.
196
197Any outputs made to a code:XfbBuffer that is not bound to a transform
198feedback buffer is ignored.
199
200[open,refpage='vkCmdBindTransformFeedbackBuffersEXT',desc='Bind transform feedback buffers to a command buffer',type='protos']
201--
202To bind transform feedback buffers to a command buffer for use in subsequent
203drawing commands, call:
204
205include::{generated}/api/protos/vkCmdBindTransformFeedbackBuffersEXT.adoc[]
206
207  * pname:commandBuffer is the command buffer into which the command is
208    recorded.
209  * pname:firstBinding is the index of the first transform feedback binding
210    whose state is updated by the command.
211  * pname:bindingCount is the number of transform feedback bindings whose
212    state is updated by the command.
213  * pname:pBuffers is a pointer to an array of buffer handles.
214  * pname:pOffsets is a pointer to an array of buffer offsets.
215  * pname:pSizes is `NULL` or a pointer to an array of basetype:VkDeviceSize
216    buffer sizes, specifying the maximum number of bytes to capture to the
217    corresponding transform feedback buffer.
218    If pname:pSizes is `NULL`, or the value of the pname:pSizes array
219    element is ename:VK_WHOLE_SIZE, then the maximum number of bytes
220    captured will be the size of the corresponding buffer minus the buffer
221    offset.
222
223The values taken from elements [eq]#i# of pname:pBuffers, pname:pOffsets and
224pname:pSizes replace the current state for the transform feedback binding
225[eq]#pname:firstBinding {plus} i#, for [eq]#i# in [eq]#[0,
226pname:bindingCount)#.
227The transform feedback binding is updated to start at the offset indicated
228by pname:pOffsets[i] from the start of the buffer pname:pBuffers[i].
229
230.Valid Usage
231****
232  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-transformFeedback-02355]]
233    sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:transformFeedback
234    must: be enabled
235  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02356]]
236    pname:firstBinding must: be less than
237    sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers
238  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357]]
239    The sum of pname:firstBinding and pname:bindingCount must: be less than
240    or equal to
241    sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers
242  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02358]]
243    All elements of pname:pOffsets must: be less than the size of the
244    corresponding element in pname:pBuffers
245  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02359]]
246    All elements of pname:pOffsets must: be a multiple of 4
247  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02360]]
248    All elements of pname:pBuffers must: have been created with the
249    ename:VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT flag
250  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pSize-02361]]
251    If the optional pname:pSize array is specified, each element of
252    pname:pSizes must: either be ename:VK_WHOLE_SIZE, or be less than or
253    equal to
254    sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBufferSize
255  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pSizes-02362]]
256    All elements of pname:pSizes must: be either ename:VK_WHOLE_SIZE, or
257    less than or equal to the size of the corresponding buffer in
258    pname:pBuffers
259  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363]]
260    All elements of pname:pOffsets plus pname:pSizes, where the
261    pname:pSizes, element is not ename:VK_WHOLE_SIZE, must: be less than or
262    equal to the size of the corresponding buffer in pname:pBuffers
263  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02364]]
264    Each element of pname:pBuffers that is non-sparse must: be bound
265    completely and contiguously to a single sname:VkDeviceMemory object
266  * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-None-02365]]
267    Transform feedback must: not be active when the
268    fname:vkCmdBindTransformFeedbackBuffersEXT command is recorded
269****
270
271include::{generated}/validity/protos/vkCmdBindTransformFeedbackBuffersEXT.adoc[]
272--
273
274[open,refpage='vkCmdBeginTransformFeedbackEXT',desc='Make transform feedback active in the command buffer',type='protos']
275--
276Transform feedback for specific transform feedback buffers is made active by
277calling:
278
279include::{generated}/api/protos/vkCmdBeginTransformFeedbackEXT.adoc[]
280
281  * pname:commandBuffer is the command buffer into which the command is
282    recorded.
283  * pname:firstCounterBuffer is the index of the first transform feedback
284    buffer corresponding to pname:pCounterBuffers[0] and
285    pname:pCounterBufferOffsets[0].
286  * pname:counterBufferCount is the size of the pname:pCounterBuffers and
287    pname:pCounterBufferOffsets arrays.
288  * pname:pCounterBuffers is `NULL` or a pointer to an array of
289    slink:VkBuffer handles to counter buffers.
290    Each buffer contains a 4 byte integer value representing the byte offset
291    from the start of the corresponding transform feedback buffer from where
292    to start capturing vertex data.
293    If the byte offset stored to the counter buffer location was done using
294    flink:vkCmdEndTransformFeedbackEXT it can be used to resume transform
295    feedback from the previous location.
296    If pname:pCounterBuffers is `NULL`, then transform feedback will start
297    capturing vertex data to byte offset zero in all bound transform
298    feedback buffers.
299    For each element of pname:pCounterBuffers that is dlink:VK_NULL_HANDLE,
300    transform feedback will start capturing vertex data to byte zero in the
301    corresponding bound transform feedback buffer.
302  * pname:pCounterBufferOffsets is `NULL` or a pointer to an array of
303    basetype:VkDeviceSize values specifying offsets within each of the
304    pname:pCounterBuffers where the counter values were previously written.
305    The location in each counter buffer at these offsets must: be large
306    enough to contain 4 bytes of data.
307    This data is the number of bytes captured by the previous transform
308    feedback to this buffer.
309    If pname:pCounterBufferOffsets is `NULL`, then it is assumed the offsets
310    are zero.
311
312The active transform feedback buffers will capture primitives emitted from
313the corresponding code:XfbBuffer in the bound graphics pipeline.
314Any code:XfbBuffer emitted that does not output to an active transform
315feedback buffer will not be captured.
316
317.Valid Usage
318****
319  * [[VUID-vkCmdBeginTransformFeedbackEXT-transformFeedback-02366]]
320    sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:transformFeedback
321    must: be enabled
322  * [[VUID-vkCmdBeginTransformFeedbackEXT-None-02367]]
323    Transform feedback must: not be active
324  * [[VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02368]]
325    pname:firstCounterBuffer must: be less than
326    sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers
327  * [[VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369]]
328    The sum of pname:firstCounterBuffer and pname:counterBufferCount must:
329    be less than or equal to
330    sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers
331  * [[VUID-vkCmdBeginTransformFeedbackEXT-counterBufferCount-02607]]
332    If pname:counterBufferCount is not `0`, and pname:pCounterBuffers is not
333    `NULL`, pname:pCounterBuffers must: be a valid pointer to an array of
334    pname:counterBufferCount sname:VkBuffer handles that are either valid or
335    dlink:VK_NULL_HANDLE
336  * [[VUID-vkCmdBeginTransformFeedbackEXT-pCounterBufferOffsets-02370]]
337    For each buffer handle in the array, if it is not dlink:VK_NULL_HANDLE
338    it must: reference a buffer large enough to hold 4 bytes at the
339    corresponding offset from the pname:pCounterBufferOffsets array
340  * [[VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffer-02371]]
341    If pname:pCounterBuffer is `NULL`, then pname:pCounterBufferOffsets
342    must: also be `NULL`
343  * [[VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffers-02372]]
344    For each buffer handle in the pname:pCounterBuffers array that is not
345    dlink:VK_NULL_HANDLE it must: have been created with a pname:usage value
346    containing
347    ename:VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT
348  * [[VUID-vkCmdBeginTransformFeedbackEXT-None-06233]]
349    A valid graphics pipeline must: be bound to
350    ename:VK_PIPELINE_BIND_POINT_GRAPHICS
351  * [[VUID-vkCmdBeginTransformFeedbackEXT-None-04128]]
352    The last
353    <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader
354    stage>> of the bound graphics pipeline must: have been declared with the
355    code:Xfb execution mode
356ifdef::VK_VERSION_1_1,VK_KHR_multiview[]
357  * [[VUID-vkCmdBeginTransformFeedbackEXT-None-02373]]
358    Transform feedback must: not be made active in a render pass instance
359    with multiview enabled
360endif::VK_VERSION_1_1,VK_KHR_multiview[]
361****
362
363include::{generated}/validity/protos/vkCmdBeginTransformFeedbackEXT.adoc[]
364--
365
366[open,refpage='vkCmdEndTransformFeedbackEXT',desc='Make transform feedback inactive in the command buffer',type='protos']
367--
368Transform feedback for specific transform feedback buffers is made inactive
369by calling:
370
371include::{generated}/api/protos/vkCmdEndTransformFeedbackEXT.adoc[]
372
373  * pname:commandBuffer is the command buffer into which the command is
374    recorded.
375  * pname:firstCounterBuffer is the index of the first transform feedback
376    buffer corresponding to pname:pCounterBuffers[0] and
377    pname:pCounterBufferOffsets[0].
378  * pname:counterBufferCount is the size of the pname:pCounterBuffers and
379    pname:pCounterBufferOffsets arrays.
380  * pname:pCounterBuffers is `NULL` or a pointer to an array of
381    slink:VkBuffer handles to counter buffers.
382    The counter buffers are used to record the current byte positions of
383    each transform feedback buffer where the next vertex output data would
384    be captured.
385    This can: be used by a subsequent flink:vkCmdBeginTransformFeedbackEXT
386    call to resume transform feedback capture from this position.
387    It can also be used by flink:vkCmdDrawIndirectByteCountEXT to determine
388    the vertex count of the draw call.
389  * pname:pCounterBufferOffsets is `NULL` or a pointer to an array of
390    basetype:VkDeviceSize values specifying offsets within each of the
391    pname:pCounterBuffers where the counter values can be written.
392    The location in each counter buffer at these offsets must: be large
393    enough to contain 4 bytes of data.
394    The data stored at this location is the byte offset from the start of
395    the transform feedback buffer binding where the next vertex data would
396    be written.
397    If pname:pCounterBufferOffsets is `NULL`, then it is assumed the offsets
398    are zero.
399
400.Valid Usage
401****
402  * [[VUID-vkCmdEndTransformFeedbackEXT-transformFeedback-02374]]
403    sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:transformFeedback
404    must: be enabled
405  * [[VUID-vkCmdEndTransformFeedbackEXT-None-02375]]
406    Transform feedback must: be active
407  * [[VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02376]]
408    pname:firstCounterBuffer must: be less than
409    sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers
410  * [[VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377]]
411    The sum of pname:firstCounterBuffer and pname:counterBufferCount must:
412    be less than or equal to
413    sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers
414  * [[VUID-vkCmdEndTransformFeedbackEXT-counterBufferCount-02608]]
415    If pname:counterBufferCount is not `0`, and pname:pCounterBuffers is not
416    `NULL`, pname:pCounterBuffers must: be a valid pointer to an array of
417    pname:counterBufferCount sname:VkBuffer handles that are either valid or
418    dlink:VK_NULL_HANDLE
419  * [[VUID-vkCmdEndTransformFeedbackEXT-pCounterBufferOffsets-02378]]
420    For each buffer handle in the array, if it is not dlink:VK_NULL_HANDLE
421    it must: reference a buffer large enough to hold 4 bytes at the
422    corresponding offset from the pname:pCounterBufferOffsets array
423  * [[VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffer-02379]]
424    If pname:pCounterBuffer is `NULL`, then pname:pCounterBufferOffsets
425    must: also be `NULL`
426  * [[VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffers-02380]]
427    For each buffer handle in the pname:pCounterBuffers array that is not
428    dlink:VK_NULL_HANDLE it must: have been created with a pname:usage value
429    containing
430    ename:VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT
431****
432
433include::{generated}/validity/protos/vkCmdEndTransformFeedbackEXT.adoc[]
434--
435endif::VK_EXT_transform_feedback[]
436
437
438ifdef::VK_NV_viewport_swizzle[]
439[[vertexpostproc-viewport-swizzle]]
440== Viewport Swizzle
441
442[open,refpage='VkPipelineViewportSwizzleStateCreateInfoNV',desc='Structure specifying swizzle applied to primitive clip coordinates',type='structs']
443--
444Each primitive sent to a given viewport has a swizzle and optional: negation
445applied to its clip coordinates.
446The swizzle that is applied depends on the viewport index, and is controlled
447by the sname:VkPipelineViewportSwizzleStateCreateInfoNV pipeline state:
448
449include::{generated}/api/structs/VkPipelineViewportSwizzleStateCreateInfoNV.adoc[]
450
451  * pname:sType is the type of this structure.
452  * pname:pNext is `NULL` or a pointer to a structure extending this
453    structure.
454  * pname:flags is reserved for future use.
455  * pname:viewportCount is the number of viewport swizzles used by the
456    pipeline.
457  * pname:pViewportSwizzles is a pointer to an array of
458    slink:VkViewportSwizzleNV structures, defining the viewport swizzles.
459
460.Valid Usage
461****
462  * [[VUID-VkPipelineViewportSwizzleStateCreateInfoNV-viewportCount-01215]]
463    pname:viewportCount must: be greater than or equal to the
464    pname:viewportCount set in sname:VkPipelineViewportStateCreateInfo
465****
466
467include::{generated}/validity/structs/VkPipelineViewportSwizzleStateCreateInfoNV.adoc[]
468--
469
470[open,refpage='VkPipelineViewportSwizzleStateCreateFlagsNV',desc='Reserved for future use',type='flags']
471--
472include::{generated}/api/flags/VkPipelineViewportSwizzleStateCreateFlagsNV.adoc[]
473
474tname:VkPipelineViewportSwizzleStateCreateFlagsNV is a bitmask type for
475setting a mask, but is currently reserved for future use.
476--
477
478The sname:VkPipelineViewportSwizzleStateCreateInfoNV state is set by adding
479this structure to the pname:pNext chain of a
480sname:VkPipelineViewportStateCreateInfo structure and setting the graphics
481pipeline state with flink:vkCreateGraphicsPipelines.
482
483ifdef::VK_EXT_extended_dynamic_state3[]
484
485[open,refpage='vkCmdSetViewportSwizzleNV',desc='Specify the viewport swizzle state dynamically for a command buffer',type='protos']
486--
487To <<pipelines-dynamic-state, dynamically set>> the viewport swizzle state,
488call:
489
490include::{generated}/api/protos/vkCmdSetViewportSwizzleNV.adoc[]
491
492  * pname:commandBuffer is the command buffer into which the command will be
493    recorded.
494  * pname:firstViewport is the index of the first viewport whose parameters
495    are updated by the command.
496  * pname:viewportCount is the number of viewports whose parameters are
497    updated by the command.
498  * pname:pViewportSwizzles is a pointer to an array of
499    slink:VkViewportSwizzleNV structures specifying viewport swizzles.
500
501This command sets the viewport swizzle state for subsequent drawing commands
502when the graphics pipeline is created with
503ename:VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV set in
504slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
505Otherwise, this state is specified by the
506slink:VkPipelineViewportSwizzleStateCreateInfoNV::pname:viewportCount, and
507slink:VkPipelineViewportSwizzleStateCreateInfoNV::pname:pViewportSwizzles
508values used to create the currently active pipeline.
509
510.Valid Usage
511****
512  * [[VUID-vkCmdSetViewportSwizzleNV-extendedDynamicState3ViewportSwizzle-07445]]
513    The <<features-extendedDynamicState3ViewportSwizzle,
514    pname:extendedDynamicState3ViewportSwizzle>> feature must: be enabled
515****
516
517include::{generated}/validity/protos/vkCmdSetViewportSwizzleNV.adoc[]
518--
519
520endif::VK_EXT_extended_dynamic_state3[]
521
522Each viewport specified from 0 to pname:viewportCount - 1 has its x,y,z,w
523swizzle state set to the corresponding pname:x, pname:y, pname:z and pname:w
524in the slink:VkViewportSwizzleNV structure.
525Each component is of type elink:VkViewportCoordinateSwizzleNV, which
526determines the type of swizzle for that component.
527The value of pname:x computes the new x component of the position as:
528
529[source,c]
530---------------------------------------------------
531if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV) x' = x;
532if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV) x' = -x;
533if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV) x' = y;
534if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV) x' = -y;
535if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV) x' = z;
536if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV) x' = -z;
537if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV) x' = w;
538if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV) x' = -w;
539---------------------------------------------------
540
541Similar selections are performed for the pname:y, pname:z, and pname:w
542coordinates.
543This swizzling is applied before clipping and perspective divide.
544If the swizzle for an active viewport index is not specified, the swizzle
545for pname:x is ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, pname:y
546is ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV, pname:z is
547ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV and pname:w is
548ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV.
549
550Viewport swizzle parameters are specified by setting the pname:pNext pointer
551of sname:VkGraphicsPipelineCreateInfo to point to a
552sname:VkPipelineViewportSwizzleStateCreateInfoNV structure.
553slink:VkPipelineViewportSwizzleStateCreateInfoNV uses
554sname:VkViewportSwizzleNV to set the viewport swizzle parameters.
555
556[open,refpage='VkViewportSwizzleNV',desc='Structure specifying a viewport swizzle',type='structs']
557--
558The sname:VkViewportSwizzleNV structure is defined as:
559
560include::{generated}/api/structs/VkViewportSwizzleNV.adoc[]
561
562  * pname:x is a elink:VkViewportCoordinateSwizzleNV value specifying the
563    swizzle operation to apply to the x component of the primitive
564  * pname:y is a elink:VkViewportCoordinateSwizzleNV value specifying the
565    swizzle operation to apply to the y component of the primitive
566  * pname:z is a elink:VkViewportCoordinateSwizzleNV value specifying the
567    swizzle operation to apply to the z component of the primitive
568  * pname:w is a elink:VkViewportCoordinateSwizzleNV value specifying the
569    swizzle operation to apply to the w component of the primitive
570
571include::{generated}/validity/structs/VkViewportSwizzleNV.adoc[]
572--
573
574[open,refpage='VkViewportCoordinateSwizzleNV',desc='Specify how a viewport coordinate is swizzled',type='enums']
575--
576Possible values of the slink:VkViewportSwizzleNV::pname:x, pname:y, pname:z,
577and pname:w members, specifying swizzling of the corresponding components of
578primitives, are:
579
580include::{generated}/api/enums/VkViewportCoordinateSwizzleNV.adoc[]
581
582These values are described in detail in <<vertexpostproc-viewport-swizzle,
583Viewport Swizzle>>.
584--
585endif::VK_NV_viewport_swizzle[]
586
587
588[[vertexpostproc-flatshading]]
589== Flat Shading
590
591_Flat shading_ a vertex output attribute means to assign all vertices of the
592primitive the same value for that output.
593The output values assigned are those of the _provoking vertex_ of the
594primitive.
595Flat shading is applied to those vertex attributes that
596<<interfaces-iointerfaces-matching,match>> fragment input attributes which
597are decorated as code:Flat.
598
599If neither
600ifdef::VK_EXT_mesh_shader,VK_NV_mesh_shader[]
601<<mesh, mesh>>,
602endif::VK_EXT_mesh_shader,VK_NV_mesh_shader[]
603<<geometry,geometry>> nor <<tessellation,tessellation shading>> is active,
604the provoking vertex is determined by the <<drawing-primitive-topologies,
605primitive topology>> defined by
606slink:VkPipelineInputAssemblyStateCreateInfo:pname:topology used to execute
607the <<drawing,drawing command>>.
608
609ifdef::VK_NV_mesh_shader[]
610If a shader using code:MeshNV {ExecutionModel} is active, the provoking
611vertex is determined by the <<drawing-primitive-topologies, primitive
612topology>> defined by the <<drawing-point-lists, code:OutputPoints>>,
613<<drawing-line-lists, code:OutputLinesNV>>, or <<drawing-triangle-lists,
614code:OutputTrianglesNV>> execution mode.
615endif::VK_NV_mesh_shader[]
616
617ifdef::VK_EXT_mesh_shader[]
618If a shader using code:MeshEXT {ExecutionModel} is active, the provoking
619vertex is determined by the <<drawing-primitive-topologies, primitive
620topology>> defined by the <<drawing-point-lists, code:OutputPoints>>,
621<<drawing-line-lists, code:OutputLinesEXT>>, or <<drawing-triangle-lists,
622code:OutputTrianglesEXT>> execution mode.
623endif::VK_EXT_mesh_shader[]
624
625If <<geometry,geometry shading>> is active, the provoking vertex is
626determined by the <<drawing-primitive-topologies, primitive topology>>
627defined by the <<drawing-point-lists, code:OutputPoints>>,
628<<drawing-line-strips, code:OutputLineStrips>>, or
629<<drawing-triangle-strips, code:OutputTriangleStrips>> execution mode.
630
631If <<tessellation,tessellation shading>> is active but <<geometry,geometry
632shading>> is not, the provoking vertex may: be any of the vertices in each
633primitive.
634
635ifdef::VK_EXT_provoking_vertex[]
636[open,refpage='VkPipelineRasterizationProvokingVertexStateCreateInfoEXT',desc='Structure specifying provoking vertex mode used by a graphics pipeline',type='structs']
637--
638For a given primitive topology, the pipeline's provoking vertex mode
639determines which vertex is the provoking vertex.
640To specify the provoking vertex mode, include a
641sname:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT structure in
642the slink:VkPipelineRasterizationStateCreateInfo::pname:pNext chain when
643creating the pipeline.
644
645The sname:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT structure
646is defined as:
647
648include::{generated}/api/structs/VkPipelineRasterizationProvokingVertexStateCreateInfoEXT.adoc[]
649
650  * pname:sType is the type of this structure.
651  * pname:pNext is `NULL` or a pointer to a structure extending this
652    structure.
653  * pname:provokingVertexMode is a elink:VkProvokingVertexModeEXT value
654    selecting the provoking vertex mode.
655
656If this struct is not provided when creating the pipeline, the pipeline will
657use the ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT mode.
658
659If the <<limits-provokingVertexModePerPipeline,
660pname:provokingVertexModePerPipeline>> limit is ename:VK_FALSE, then all
661pipelines bound within a render pass instance must: have the same
662pname:provokingVertexMode.
663
664.Valid Usage
665****
666  * [[VUID-VkPipelineRasterizationProvokingVertexStateCreateInfoEXT-provokingVertexMode-04883]]
667    If pname:provokingVertexMode is
668    ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, then the
669    <<features-provokingVertexLast, pname:provokingVertexLast>> feature
670    must: be enabled
671****
672
673include::{generated}/validity/structs/VkPipelineRasterizationProvokingVertexStateCreateInfoEXT.adoc[]
674--
675
676[open,refpage='VkProvokingVertexModeEXT',desc='Specify which vertex in a primitive is the provoking vertex',type='enums']
677--
678Possible values of
679slink:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::pname:provokingVertexMode
680are:
681
682include::{generated}/api/enums/VkProvokingVertexModeEXT.adoc[]
683
684  * ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT specifies that the
685    provoking vertex is the first non-adjacency vertex in the list of
686    vertices used by a primitive.
687  * ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT specifies that the
688    provoking vertex is the last non-adjacency vertex in the list of
689    vertices used by a primitive.
690
691These modes are described more precisely in
692<<drawing-primitive-topologies,Primitive Topologies>>.
693--
694
695ifdef::VK_EXT_extended_dynamic_state3[]
696
697[open,refpage='vkCmdSetProvokingVertexModeEXT',desc='Specify the provoking vertex mode dynamically for a command buffer',type='protos']
698--
699To <<pipelines-dynamic-state, dynamically set>> the
700pname:provokingVertexMode state, call:
701
702include::{generated}/api/protos/vkCmdSetProvokingVertexModeEXT.adoc[]
703
704  * pname:commandBuffer is the command buffer into which the command will be
705    recorded.
706  * pname:provokingVertexMode specifies the pname:provokingVertexMode state.
707
708This command sets the pname:provokingVertexMode state for subsequent drawing
709commands when the graphics pipeline is created with
710ename:VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT set in
711slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
712Otherwise, this state is specified by the
713slink:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::pname:provokingVertexMode
714value used to create the currently active pipeline.
715
716.Valid Usage
717****
718  * [[VUID-vkCmdSetProvokingVertexModeEXT-extendedDynamicState3ProvokingVertexMode-07446]]
719    The <<features-extendedDynamicState3ProvokingVertexMode,
720    pname:extendedDynamicState3ProvokingVertexMode>> feature must: be
721    enabled
722  * [[VUID-vkCmdSetProvokingVertexModeEXT-provokingVertexMode-07447]]
723    If pname:provokingVertexMode is
724    ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, then the
725    <<features-provokingVertexLast, pname:provokingVertexLast>> feature
726    must: be enabled
727****
728
729include::{generated}/validity/protos/vkCmdSetProvokingVertexModeEXT.adoc[]
730--
731
732endif::VK_EXT_extended_dynamic_state3[]
733
734endif::VK_EXT_provoking_vertex[]
735
736
737[[vertexpostproc-clipping]]
738== Primitive Clipping
739
740Primitives are culled against the _cull volume_ and then clipped to the
741_clip volume_.
742In clip coordinates, the _view volume_ is defined by:
743
744[latexmath]
745++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
746\begin{array}{c}
747-w_c \leq x_c \leq w_c \\
748-w_c \leq y_c \leq w_c \\
749z_m \leq z_c \leq w_c
750\end{array}
751++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
752
753where
754ifdef::VK_EXT_depth_clip_control[]
755if
756slink:VkPipelineViewportDepthClipControlCreateInfoEXT::pname:negativeOneToOne
757is ename:VK_TRUE [eq]#z~m~# is equal to [eq]#-w~c~# otherwise
758endif::VK_EXT_depth_clip_control[]
759[eq]#z~m~# is equal to zero.
760
761This view volume can: be further restricted by as many as
762sname:VkPhysicalDeviceLimits::pname:maxClipDistances client-defined
763half-spaces.
764
765The cull volume is the intersection of up to
766sname:VkPhysicalDeviceLimits::pname:maxCullDistances client-defined
767half-spaces (if no client-defined cull half-spaces are enabled, culling
768against the cull volume is skipped).
769
770A shader must: write a single cull distance for each enabled cull half-space
771to elements of the code:CullDistance array.
772If the cull distance for any enabled cull half-space is negative for all of
773the vertices of the primitive under consideration, the primitive is
774discarded.
775Otherwise the primitive is clipped against the clip volume as defined below.
776
777The clip volume is the intersection of up to
778sname:VkPhysicalDeviceLimits::pname:maxClipDistances client-defined
779half-spaces with the view volume (if no client-defined clip half-spaces are
780enabled, the clip volume is the view volume).
781
782A shader must: write a single clip distance for each enabled clip half-space
783to elements of the code:ClipDistance array.
784Clip half-space [eq]#i# is then given by the set of points satisfying the
785inequality
786
787  {empty}:: [eq]#c~i~(**P**) {geq} 0#
788
789where [eq]#c~i~(**P**)# is the clip distance [eq]#i# at point [eq]#**P**#.
790For point primitives, [eq]#c~i~(**P**)# is simply the clip distance for the
791vertex in question.
792For line and triangle primitives, per-vertex clip distances are interpolated
793using a weighted mean, with weights derived according to the algorithms
794described in sections <<primsrast-lines-basic,Basic Line Segment
795Rasterization>> and <<primsrast-polygons-basic,Basic Polygon
796Rasterization>>, using the perspective interpolation equations.
797
798The number of client-defined clip and cull half-spaces that are enabled is
799determined by the explicit size of the built-in arrays code:ClipDistance and
800code:CullDistance, respectively, declared as an output in the interface of
801the entry point of the final shader stage before clipping.
802
803ifdef::VK_EXT_depth_clip_enable[]
804If slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT is present in
805the graphics pipeline state then depth clipping is disabled if
806slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT::pname:depthClipEnable
807is ename:VK_FALSE.
808Otherwise, if slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT is
809not present, depth clipping is disabled when
810slink:VkPipelineRasterizationStateCreateInfo::pname:depthClampEnable is
811ename:VK_TRUE.
812endif::VK_EXT_depth_clip_enable[]
813ifndef::VK_EXT_depth_clip_enable[]
814Depth clamping is enabled or disabled via the pname:depthClampEnable enable
815of the slink:VkPipelineRasterizationStateCreateInfo structure.
816Depth clipping is disabled when pname:depthClampEnable is ename:VK_TRUE.
817endif::VK_EXT_depth_clip_enable[]
818
819ifdef::VK_EXT_extended_dynamic_state3[]
820
821[open,refpage='vkCmdSetDepthClampEnableEXT',desc='Specify dynamically whether depth clamping is enabled in the command buffer',type='protos']
822--
823To <<pipelines-dynamic-state, dynamically set>> enable or disable depth
824clamping, call:
825
826include::{generated}/api/protos/vkCmdSetDepthClampEnableEXT.adoc[]
827
828  * pname:commandBuffer is the command buffer into which the command will be
829    recorded.
830  * pname:depthClampEnable specifies whether depth clamping is enabled.
831
832This command sets whether depth clamping is enabled or disabled for
833subsequent drawing commands when the graphics pipeline is created with
834ename:VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT set in
835slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
836Otherwise, this state is specified by the
837slink:VkPipelineRasterizationStateCreateInfo::pname:depthClampEnable value
838used to create the currently active pipeline.
839
840If the depth clamping state is changed dynamically, and the pipeline was not
841created with ename:VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT enabled, then
842depth clipping is enabled when depth clamping is disabled and vice versa.
843
844.Valid Usage
845****
846  * [[VUID-vkCmdSetDepthClampEnableEXT-extendedDynamicState3DepthClampEnable-07448]]
847    The <<features-extendedDynamicState3DepthClampEnable,
848    pname:extendedDynamicState3DepthClampEnable>> feature must: be enabled
849  * [[VUID-vkCmdSetDepthClampEnableEXT-depthClamp-07449]]
850    If the <<features-depthClamp, pname:depthClamp>> feature is not enabled,
851    pname:depthClampEnable must be ename:VK_FALSE
852****
853
854include::{generated}/validity/protos/vkCmdSetDepthClampEnableEXT.adoc[]
855--
856
857ifdef::VK_EXT_depth_clip_enable[]
858[open,refpage='vkCmdSetDepthClipEnableEXT',desc='Specify dynamically whether depth clipping is enabled in the command buffer',type='protos']
859--
860To <<pipelines-dynamic-state, dynamically set>> enable or disable depth
861clipping, call:
862
863include::{generated}/api/protos/vkCmdSetDepthClipEnableEXT.adoc[]
864
865  * pname:commandBuffer is the command buffer into which the command will be
866    recorded.
867  * pname:depthClipEnable specifies whether depth clipping is enabled.
868
869This command sets whether depth clipping is enabled or disabled for
870subsequent drawing commands when the graphics pipeline is created with
871ename:VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT set in
872slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
873Otherwise, this state is specified by the
874slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT::pname:depthClipEnable
875value used to create the currently active pipeline, or is set to the inverse
876of slink:VkPipelineRasterizationStateCreateInfo::pname:depthClampEnable if
877sname:VkPipelineRasterizationDepthClipStateCreateInfoEXT is not specified.
878
879.Valid Usage
880****
881  * [[VUID-vkCmdSetDepthClipEnableEXT-extendedDynamicState3DepthClipEnable-07450]]
882    The <<features-extendedDynamicState3DepthClipEnable,
883    pname:extendedDynamicState3DepthClipEnable>> feature must: be enabled
884  * [[VUID-vkCmdSetDepthClipEnableEXT-depthClipEnable-07451]]
885    The <<features-depthClipEnable, pname:depthClipEnable>> feature must: be
886    enabled
887****
888
889include::{generated}/validity/protos/vkCmdSetDepthClipEnableEXT.adoc[]
890--
891endif::VK_EXT_depth_clip_enable[]
892
893endif::VK_EXT_extended_dynamic_state3[]
894
895When depth clipping is disabled, the plane equation
896
897  {empty}:: [eq]#z~m~ {leq} z~c~ {leq} w~c~#
898
899(see the clip volume definition above) is ignored by view volume clipping
900(effectively, there is no near or far plane clipping).
901
902If the primitive under consideration is a point or line segment, then
903clipping passes it unchanged if its vertices lie entirely within the clip
904volume.
905
906ifndef::VK_VERSION_1_1,VK_KHR_maintenance2[]
907If a point's vertex lies outside of the clip volume, the entire primitive
908may: be discarded.
909endif::VK_VERSION_1_1,VK_KHR_maintenance2[]
910
911ifdef::VK_VERSION_1_1,VK_KHR_maintenance2[]
912[open,refpage='VkPointClippingBehavior',desc='Enum specifying the point clipping behavior',type='enums']
913--
914Possible values of
915slink:VkPhysicalDevicePointClippingProperties::pname:pointClippingBehavior,
916specifying clipping behavior of a point primitive whose vertex lies outside
917the clip volume, are:
918
919include::{generated}/api/enums/VkPointClippingBehavior.adoc[]
920
921ifdef::VK_KHR_maintenance2[]
922or the equivalent
923
924include::{generated}/api/enums/VkPointClippingBehaviorKHR.adoc[]
925endif::VK_KHR_maintenance2[]
926
927  * ename:VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES specifies that the
928    primitive is discarded if the vertex lies outside any clip plane,
929    including the planes bounding the view volume.
930  * ename:VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY specifies that
931    the primitive is discarded only if the vertex lies outside any user clip
932    plane.
933--
934endif::VK_VERSION_1_1,VK_KHR_maintenance2[]
935
936If either of a line segment's vertices lie outside of the clip volume, the
937line segment may: be clipped, with new vertex coordinates computed for each
938vertex that lies outside the clip volume.
939A clipped line segment endpoint lies on both the original line segment and
940the boundary of the clip volume.
941
942This clipping produces a value, [eq]#0 {leq} t {leq} 1#, for each clipped
943vertex.
944If the coordinates of a clipped vertex are [eq]#**P**# and the unclipped
945line segment's vertex coordinates are [eq]#**P**~1~# and [eq]#**P**~2~#,
946then [eq]#t# satisfies the following equation
947
948  {empty}:: [eq]#**P** = t **P**~1~ {plus} (1-t) **P**~2~#.
949
950[eq]#t# is used to clip vertex output attributes as described in
951<<vertexpostproc-clipping-shader-outputs,Clipping Shader Outputs>>.
952
953If the primitive is a polygon, it passes unchanged if every one of its edges
954lies entirely inside the clip volume, and is either clipped or discarded
955otherwise.
956If the edges of the polygon intersect the boundary of the clip volume, the
957intersecting edges are reconnected by new edges that lie along the boundary
958of the clip volume - in some cases requiring the introduction of new
959vertices into a polygon.
960
961If a polygon intersects an edge of the clip volume's boundary, the clipped
962polygon must: include a point on this boundary edge.
963
964Primitives rendered with user-defined half-spaces must: satisfy a
965complementarity criterion.
966Suppose a series of primitives is drawn where each vertex [eq]#i# has a
967single specified clip distance [eq]#d~i~# (or a number of similarly
968specified clip distances, if multiple half-spaces are enabled).
969Next, suppose that the same series of primitives are drawn again with each
970such clip distance replaced by [eq]#-d~i~# (and the graphics pipeline is
971otherwise the same).
972In this case, primitives must: not be missing any pixels, and pixels must:
973not be drawn twice in regions where those primitives are cut by the clip
974planes.
975
976ifdef::VK_EXT_depth_clip_control[]
977[open,refpage='VkPipelineViewportDepthClipControlCreateInfoEXT',desc='Structure specifying parameters of a newly created pipeline depth clip control state',type='structs']
978--
979The sname:VkPipelineViewportDepthClipControlCreateInfoEXT structure is
980defined as:
981
982include::{generated}/api/structs/VkPipelineViewportDepthClipControlCreateInfoEXT.adoc[]
983
984  * pname:sType is the type of this structure.
985  * pname:pNext is `NULL` or a pointer to a structure extending this
986    structure.
987  * pname:negativeOneToOne sets the [eq]#z~m~# in the _view volume_ to
988    [eq]#-w~c~#
989
990.Valid Usage
991****
992  * [[VUID-VkPipelineViewportDepthClipControlCreateInfoEXT-negativeOneToOne-06470]]
993    If <<features-depthClipControl, pname:depthClipControl>> is not enabled,
994    pname:negativeOneToOne must: be ename:VK_FALSE
995****
996
997include::{generated}/validity/structs/VkPipelineViewportDepthClipControlCreateInfoEXT.adoc[]
998--
999
1000ifdef::VK_EXT_extended_dynamic_state3[]
1001[open,refpage='vkCmdSetDepthClipNegativeOneToOneEXT',desc='Specify the negative one to one depth clip mode dynamically for a command buffer',type='protos']
1002--
1003To <<pipelines-dynamic-state, dynamically set>> pname:negativeOneToOne,
1004call:
1005
1006include::{generated}/api/protos/vkCmdSetDepthClipNegativeOneToOneEXT.adoc[]
1007
1008  * pname:commandBuffer is the command buffer into which the command will be
1009    recorded.
1010  * pname:negativeOneToOne specifies the pname:negativeOneToOne state.
1011
1012This command sets the pname:negativeOneToOne state for subsequent drawing
1013commands when the graphics pipeline is created with
1014ename:VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT set in
1015slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
1016Otherwise, this state is specified by the
1017slink:VkPipelineViewportDepthClipControlCreateInfoEXT::pname:negativeOneToOne
1018value used to create the currently active pipeline.
1019
1020.Valid Usage
1021****
1022  * [[VUID-vkCmdSetDepthClipNegativeOneToOneEXT-extendedDynamicState3DepthClipNegativeOneToOne-07452]]
1023    The <<features-extendedDynamicState3DepthClipNegativeOneToOne,
1024    pname:extendedDynamicState3DepthClipNegativeOneToOne>> feature must: be
1025    enabled
1026  * [[VUID-vkCmdSetDepthClipNegativeOneToOneEXT-depthClipControl-07453]]
1027    The <<features-depthClipControl, pname:depthClipControl>> feature must:
1028    be enabled
1029****
1030
1031include::{generated}/validity/protos/vkCmdSetDepthClipNegativeOneToOneEXT.adoc[]
1032--
1033endif::VK_EXT_extended_dynamic_state3[]
1034endif::VK_EXT_depth_clip_control[]
1035
1036
1037[[vertexpostproc-clipping-shader-outputs]]
1038== Clipping Shader Outputs
1039
1040Next, vertex output attributes are clipped.
1041The output values associated with a vertex that lies within the clip volume
1042are unaffected by clipping.
1043If a primitive is clipped, however, the output values assigned to vertices
1044produced by clipping are clipped.
1045
1046Let the output values assigned to the two vertices [eq]#**P**~1~# and
1047[eq]#**P**~2~# of an unclipped edge be [eq]#**c**~1~# and [eq]#**c**~2~#.
1048The value of [eq]#t# (see <<vertexpostproc-clipping,Primitive Clipping>>)
1049for a clipped point [eq]#**P**# is used to obtain the output value
1050associated with [eq]#**P**# as
1051
1052  {empty}:: [eq]#**c** = t **c**~1~ {plus} (1-t) **c**~2~#.
1053
1054(Multiplying an output value by a scalar means multiplying each of _x_, _y_,
1055_z_, and _w_ by the scalar.)
1056
1057Since this computation is performed in clip space before division by
1058[eq]#w~c~#, clipped output values are perspective-correct.
1059
1060Polygon clipping creates a clipped vertex along an edge of the clip volume's
1061boundary.
1062This situation is handled by noting that polygon clipping proceeds by
1063clipping against one half-space at a time.
1064Output value clipping is done in the same way, so that clipped points always
1065occur at the intersection of polygon edges (possibly already clipped) with
1066the clip volume's boundary.
1067
1068For vertex output attributes whose matching fragment input attributes are
1069decorated with code:NoPerspective, the value of [eq]#t# used to obtain the
1070output value associated with [eq]#**P**# will be adjusted to produce results
1071that vary linearly in framebuffer space.
1072
1073Output attributes of integer or unsigned integer type must: always be flat
1074shaded.
1075Flat shaded attributes are constant over the primitive being rasterized (see
1076<<primsrast-lines-basic,Basic Line Segment Rasterization>> and
1077<<primsrast-polygons-basic,Basic Polygon Rasterization>>), and no
1078interpolation is performed.
1079The output value [eq]#**c**# is taken from either [eq]#**c**~1~# or
1080[eq]#**c**~2~#, since flat shading has already occurred and the two values
1081are identical.
1082
1083ifdef::VK_NV_clip_space_w_scaling[]
1084include::{chapters}/VK_NV_clip_space_w_scaling/vertexpostproc.adoc[]
1085endif::VK_NV_clip_space_w_scaling[]
1086
1087
1088[[vertexpostproc-coord-transform]]
1089== Coordinate Transformations
1090
1091_Clip coordinates_ for a vertex result from shader execution, which yields a
1092vertex coordinate code:Position.
1093
1094Perspective division on clip coordinates yields _normalized device
1095coordinates_, followed by a _viewport_ transformation (see
1096<<vertexpostproc-viewport,Controlling the Viewport>>) to convert these
1097coordinates into _framebuffer coordinates_.
1098
1099If a vertex in clip coordinates has a position given by
1100
1101[latexmath]
1102++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1103\left(\begin{array}{c}
1104x_c \\
1105y_c \\
1106z_c \\
1107w_c
1108\end{array}\right)
1109++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1110
1111then the vertex's normalized device coordinates are
1112[latexmath]
1113++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1114\left(
1115        \begin{array}{c}
1116                x_d \\
1117                y_d \\
1118                z_d
1119        \end{array}
1120\right) =
1121\left(
1122        \begin{array}{c}
1123                \frac{x_c}{w_c} \\
1124                \frac{y_c}{w_c} \\
1125                \frac{z_c}{w_c}
1126        \end{array}
1127\right)
1128++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1129
1130
1131ifdef::VK_QCOM_render_pass_transform[]
1132[[vertexpostproc-renderpass-transform]]
1133== Render Pass Transform
1134
1135A _render pass transform_ can: be enabled for render pass instances.
1136The clip coordinates [eq]#(x~c~, y~c~)# that result from vertex shader
1137execution are transformed by a rotation of 0, 90, 180, or 270 degrees in the
1138XY plane, centered at the origin.
1139
1140When _Render pass transform_ is enabled, the transform applies to all
1141primitives for all subpasses of the render pass.
1142The transformed vertex in clip coordinates has a position given by
1143
1144[latexmath]
1145++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1146\left(
1147        \begin{array}{c}
1148                x_{c_{trans}} \\
1149                y_{c_{trans}} \\
1150                z_{c_{trans}}
1151        \end{array}
1152\right) =
1153\left(
1154        \begin{array}{c}
1155                x_{c} \cos \theta - y_{c} \sin \theta \\
1156                x_{c} \sin \theta + y_{c} \cos \theta \\
1157                z_c
1158        \end{array}
1159\right)
1160++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1161
1162where
1163
1164  * _[eq]#{theta}#_ is 0 degrees for
1165    ename:VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
1166  * _[eq]#{theta}#_ is 90 degrees for
1167    ename:VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR
1168  * _[eq]#{theta}#_ is 180 degrees for
1169    ename:VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR
1170  * _[eq]#{theta}#_ is 270 degrees for
1171    ename:VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR
1172
1173
1174The transformed vertex's normalized device coordinates are
1175[latexmath]
1176++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1177\left(
1178        \begin{array}{c}
1179                x_d \\
1180                y_d \\
1181                z_d
1182        \end{array}
1183\right) =
1184\left(
1185        \begin{array}{c}
1186                \frac{x_{c_{trans}}}{w_c} \\
1187                \frac{y_{c_{trans}}}{w_c} \\
1188                \frac{z_{c_{trans}}}{w_c}
1189        \end{array}
1190\right)
1191++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1192
1193
1194When render pass transform is enabled for a render pass instance, the
1195following additional features are enabled:
1196
1197  * Each slink:VkViewport specified by either
1198    slink:VkPipelineViewportStateCreateInfo::pname:pViewports or
1199    flink:vkCmdSetViewport will have its width/height [eq]#(p~x~, p~y~)# and
1200    its center [eq]#(o~x~, o~y~)# similarly transformed by the
1201    implementation.
1202  * Each scissor specified by
1203    slink:VkPipelineViewportStateCreateInfo::pname:pScissors or
1204    flink:vkCmdSetScissor will have its [eq]#(offset~x~, offset~y~)# and
1205    [eq]#(extent~x~, extent~y~)# similarly transformed by the
1206    implementation.
1207  * The pname:renderArea specified in
1208    slink:VkCommandBufferInheritanceRenderPassTransformInfoQCOM and
1209    slink:VkRenderPassBeginInfo will be similarly transformed by the
1210    implementation.
1211  * The [eq]#(x, y)# components of shader variables with built-in
1212    decorations code:FragCoord, code:SamplePosition, or code:PointCoord will
1213    be similarly transformed by the implementation.
1214  * The [eq]#(x,y)# components of the code:offset operand of the
1215    code:InterpolateAtOffset extended instruction will be similarly
1216    transformed by the implementation.
1217  * The values returned by SPIR-V <<shaders-derivative-operations,
1218    derivative instructions>> code:OpDPdx, code:OpDPdy, code:OpDPdxCourse,
1219    code:OpDPdyCourse, code:OpDPdxFine, code:OpDPdyFine will be similarly
1220    transformed by the implementation.
1221
1222
1223The net result of the above, is that applications can: act as if rendering
1224to a framebuffer oriented with the
1225slink:VkSurfaceCapabilitiesKHR::pname:currentTransform.
1226In other words, applications can: act as if the presentation engine will be
1227performing the transformation of the swapchain image after rendering and
1228prior to presentation to the user.
1229In fact, the transformation of the various items cited above are being
1230handled by the implementation as the rendering takes place.
1231
1232endif::VK_QCOM_render_pass_transform[]
1233
1234
1235[[vertexpostproc-viewport]]
1236== Controlling the Viewport
1237
1238The viewport transformation is determined by the selected viewport's width
1239and height in pixels, [eq]#p~x~# and [eq]#p~y~#, respectively, and its
1240center [eq]#(o~x~, o~y~)# (also in pixels), as well as its depth range min
1241and max determining a depth range scale value [eq]#p~z~# and a depth range
1242bias value [eq]#o~z~# (defined below).
1243The vertex's framebuffer coordinates [eq]#(x~f~, y~f~, z~f~)# are given by
1244
1245  {empty}:: [eq]#x~f~ = (p~x~ / 2) x~d~ {plus} o~x~#
1246  {empty}:: [eq]#y~f~ = (p~y~ / 2) y~d~ {plus} o~y~#
1247  {empty}:: [eq]#z~f~ = p~z~ {times} z~d~ {plus} o~z~#
1248
1249Multiple viewports are available, numbered zero up to
1250sname:VkPhysicalDeviceLimits::pname:maxViewports minus one.
1251The number of viewports used by a pipeline is controlled by the
1252pname:viewportCount member of the sname:VkPipelineViewportStateCreateInfo
1253structure used in pipeline creation.
1254
1255[eq]#x~f~# and [eq]#y~f~# have limited precision, where the number of
1256fractional bits retained is specified by
1257sname:VkPhysicalDeviceLimits::pname:subPixelPrecisionBits.
1258ifdef::VK_EXT_line_rasterization[]
1259When rasterizing <<primsrast-lines,line segments>>, the number of fractional
1260bits is specified by
1261sname:VkPhysicalDeviceLineRasterizationPropertiesEXT::pname:lineSubPixelPrecisionBits.
1262endif::VK_EXT_line_rasterization[]
1263
1264[open,refpage='VkPipelineViewportStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline viewport state',type='structs']
1265--
1266The sname:VkPipelineViewportStateCreateInfo structure is defined as:
1267
1268include::{generated}/api/structs/VkPipelineViewportStateCreateInfo.adoc[]
1269
1270  * pname:sType is the type of this structure.
1271  * pname:pNext is `NULL` or a pointer to a structure extending this
1272    structure.
1273  * pname:flags is reserved for future use.
1274  * pname:viewportCount is the number of viewports used by the pipeline.
1275  * pname:pViewports is a pointer to an array of slink:VkViewport
1276    structures, defining the viewport transforms.
1277    If the viewport state is dynamic, this member is ignored.
1278  * pname:scissorCount is the number of <<fragops-scissor,scissors>> and
1279    must: match the number of viewports.
1280  * pname:pScissors is a pointer to an array of slink:VkRect2D structures
1281    defining the rectangular bounds of the scissor for the corresponding
1282    viewport.
1283    If the scissor state is dynamic, this member is ignored.
1284
1285.Valid Usage
1286****
1287  * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216]]
1288    If the <<features-multiViewport, pname:multiViewport>> feature is not
1289    enabled, pname:viewportCount must: not be greater than `1`
1290  * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217]]
1291    If the <<features-multiViewport, pname:multiViewport>> feature is not
1292    enabled, pname:scissorCount must: not be greater than `1`
1293  * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218]]
1294    pname:viewportCount must: be less than or equal to
1295    sname:VkPhysicalDeviceLimits::pname:maxViewports
1296  * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219]]
1297    pname:scissorCount must: be less than or equal to
1298    sname:VkPhysicalDeviceLimits::pname:maxViewports
1299ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
1300  * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220]]
1301    pname:scissorCount and pname:viewportCount must: be identical
1302endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
1303  * [[VUID-VkPipelineViewportStateCreateInfo-x-02821]]
1304    The pname:x and pname:y members of pname:offset member of any element of
1305    pname:pScissors must: be greater than or equal to `0`
1306  * [[VUID-VkPipelineViewportStateCreateInfo-offset-02822]]
1307    Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# must: not
1308    cause a signed integer addition overflow for any element of
1309    pname:pScissors
1310  * [[VUID-VkPipelineViewportStateCreateInfo-offset-02823]]
1311    Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# must:
1312    not cause a signed integer addition overflow for any element of
1313    pname:pScissors
1314ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
1315  * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength]]
1316    pname:viewportCount must: be greater than `0`
1317  * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength]]
1318    pname:scissorCount must: be greater than `0`
1319endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
1320ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
1321  * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-04134]]
1322    If the graphics pipeline is being created without
1323    ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT and
1324    ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT set then pname:scissorCount
1325    and pname:viewportCount must: be identical
1326  * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135]]
1327    If the graphics pipeline is being created with
1328    ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT set then pname:viewportCount
1329    must: be `0`, otherwise it must: be greater than `0`
1330  * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136]]
1331    If the graphics pipeline is being created with
1332    ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT set then pname:scissorCount
1333    must: be `0`, otherwise it must: be greater than `0`
1334endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
1335ifdef::VK_NV_clip_space_w_scaling[]
1336  * [[VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726]]
1337    If the pname:viewportWScalingEnable member of a
1338    slink:VkPipelineViewportWScalingStateCreateInfoNV structure included in
1339    the pname:pNext chain is ename:VK_TRUE, the pname:viewportCount member
1340    of the slink:VkPipelineViewportWScalingStateCreateInfoNV structure must:
1341    be greater than or equal to
1342    slink:VkPipelineViewportStateCreateInfo::pname:viewportCount
1343endif::VK_NV_clip_space_w_scaling[]
1344****
1345
1346include::{generated}/validity/structs/VkPipelineViewportStateCreateInfo.adoc[]
1347--
1348
1349ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
1350[open,refpage='vkCmdSetViewportWithCount',desc='Set the viewport count and viewports dynamically for a command buffer',type='protos',alias='vkCmdSetViewportWithCountEXT']
1351--
1352To <<pipelines-dynamic-state, dynamically set>> the viewport count and
1353viewports, call:
1354
1355ifdef::VK_VERSION_1_3[]
1356include::{generated}/api/protos/vkCmdSetViewportWithCount.adoc[]
1357endif::VK_VERSION_1_3[]
1358
1359ifdef::VK_VERSION_1_3+VK_EXT_extended_dynamic_state[or the equivalent command]
1360
1361ifdef::VK_EXT_extended_dynamic_state[]
1362include::{generated}/api/protos/vkCmdSetViewportWithCountEXT.adoc[]
1363endif::VK_EXT_extended_dynamic_state[]
1364
1365  * pname:commandBuffer is the command buffer into which the command will be
1366    recorded.
1367  * pname:viewportCount specifies the viewport count.
1368  * pname:pViewports specifies the viewports to use for drawing.
1369
1370This command sets the viewport count and viewports state for subsequent
1371drawing commands when the graphics pipeline is created with
1372ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT set in
1373slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
1374Otherwise, this state is specified by the corresponding
1375slink:VkPipelineViewportStateCreateInfo::pname:viewportCount and
1376pname:pViewports values used to create the currently active pipeline.
1377
1378.Valid Usage
1379****
1380ifndef::VK_VERSION_1_3[]
1381  * [[VUID-vkCmdSetViewportWithCount-None-03393]]
1382    The <<features-extendedDynamicState, pname:extendedDynamicState>>
1383    feature must: be enabled
1384endif::VK_VERSION_1_3[]
1385  * [[VUID-vkCmdSetViewportWithCount-viewportCount-03394]]
1386    pname:viewportCount must: be between `1` and
1387    sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive
1388  * [[VUID-vkCmdSetViewportWithCount-viewportCount-03395]]
1389    If the <<features-multiViewport, pname:multiViewport>> feature is not
1390    enabled, pname:viewportCount must: be `1`
1391ifdef::VK_NV_inherited_viewport_scissor[]
1392  * [[VUID-vkCmdSetViewportWithCount-commandBuffer-04819]]
1393    pname:commandBuffer must: not have
1394    slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D
1395    enabled
1396endif::VK_NV_inherited_viewport_scissor[]
1397****
1398
1399include::{generated}/validity/protos/vkCmdSetViewportWithCount.adoc[]
1400--
1401
1402[open,refpage='vkCmdSetScissorWithCount',desc='Set the scissor count and scissor rectangular bounds dynamically for a command buffer',type='protos',alias='vkCmdSetScissorWithCountEXT']
1403--
1404To <<pipelines-dynamic-state, dynamically set>> the scissor count and
1405scissor rectangular bounds, call:
1406
1407ifdef::VK_VERSION_1_3[]
1408include::{generated}/api/protos/vkCmdSetScissorWithCount.adoc[]
1409endif::VK_VERSION_1_3[]
1410
1411ifdef::VK_VERSION_1_3+VK_EXT_extended_dynamic_state[or the equivalent command]
1412
1413ifdef::VK_EXT_extended_dynamic_state[]
1414include::{generated}/api/protos/vkCmdSetScissorWithCountEXT.adoc[]
1415endif::VK_EXT_extended_dynamic_state[]
1416
1417  * pname:commandBuffer is the command buffer into which the command will be
1418    recorded.
1419  * pname:scissorCount specifies the scissor count.
1420  * pname:pScissors specifies the scissors to use for drawing.
1421
1422This command sets the scissor count and scissor rectangular bounds state for
1423subsequence drawing commands when the graphics pipeline is created with
1424ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT set in
1425slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
1426Otherwise, this state is specified by the corresponding
1427slink:VkPipelineViewportStateCreateInfo::pname:scissorCount and
1428pname:pScissors values used to create the currently active pipeline.
1429
1430.Valid Usage
1431****
1432ifndef::VK_VERSION_1_3[]
1433  * [[VUID-vkCmdSetScissorWithCount-None-03396]]
1434    The <<features-extendedDynamicState, pname:extendedDynamicState>>
1435    feature must: be enabled
1436endif::VK_VERSION_1_3[]
1437  * [[VUID-vkCmdSetScissorWithCount-scissorCount-03397]]
1438    pname:scissorCount must: be between `1` and
1439    sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive
1440  * [[VUID-vkCmdSetScissorWithCount-scissorCount-03398]]
1441    If the <<features-multiViewport, pname:multiViewport>> feature is not
1442    enabled, pname:scissorCount must: be `1`
1443  * [[VUID-vkCmdSetScissorWithCount-x-03399]]
1444    The pname:x and pname:y members of pname:offset member of any element of
1445    pname:pScissors must: be greater than or equal to `0`
1446  * [[VUID-vkCmdSetScissorWithCount-offset-03400]]
1447    Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# must: not
1448    cause a signed integer addition overflow for any element of
1449    pname:pScissors
1450  * [[VUID-vkCmdSetScissorWithCount-offset-03401]]
1451    Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# must:
1452    not cause a signed integer addition overflow for any element of
1453    pname:pScissors
1454ifdef::VK_NV_inherited_viewport_scissor[]
1455  * [[VUID-vkCmdSetScissorWithCount-commandBuffer-04820]]
1456    pname:commandBuffer must: not have
1457    slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D
1458    enabled
1459endif::VK_NV_inherited_viewport_scissor[]
1460****
1461
1462include::{generated}/validity/protos/vkCmdSetScissorWithCount.adoc[]
1463--
1464endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
1465
1466[open,refpage='VkPipelineViewportStateCreateFlags',desc='Reserved for future use',type='flags']
1467--
1468include::{generated}/api/flags/VkPipelineViewportStateCreateFlags.adoc[]
1469
1470tname:VkPipelineViewportStateCreateFlags is a bitmask type for setting a
1471mask, but is currently reserved for future use.
1472--
1473
1474ifndef::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[]
1475If a geometry shader is active and has an output variable decorated with
1476code:ViewportIndex, the viewport transformation uses the viewport
1477corresponding to the value assigned to code:ViewportIndex taken from an
1478implementation-dependent vertex of each primitive.
1479If code:ViewportIndex is outside the range zero to pname:viewportCount minus
1480one for a primitive, or if the geometry shader did not assign a value to
1481code:ViewportIndex for all vertices of a primitive due to flow control, the
1482values resulting from the viewport transformation of the vertices of such
1483primitives are undefined:.
1484If no geometry shader is active, or if the geometry shader does not have an
1485output decorated with code:ViewportIndex, the viewport numbered zero is used
1486by the viewport transformation.
1487endif::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[]
1488
1489ifdef::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[]
1490ifdef::VK_NV_viewport_array2[]
1491A _<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader
1492stage>>_ can: direct each primitive to zero or more viewports.
1493The destination viewports for a primitive are selected by the last active
1494<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader
1495stage>> that has an output variable decorated with code:ViewportIndex
1496(selecting a single viewport) or code:ViewportMaskNV (selecting multiple
1497viewports).
1498The viewport transform uses the viewport corresponding to either the value
1499assigned to code:ViewportIndex or one of the bits set in
1500code:ViewportMaskNV, and taken from an implementation-dependent vertex of
1501each primitive.
1502If code:ViewportIndex or any of the bits in code:ViewportMaskNV are outside
1503the range zero to pname:viewportCount minus one for a primitive, or if the
1504last active <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization
1505shader stage>> did not assign a value to either code:ViewportIndex or
1506code:ViewportMaskNV for all vertices of a primitive due to flow control, the
1507values resulting from the viewport transformation of the vertices of such
1508primitives are undefined:.
1509If the last <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization
1510shader stage>> does not have an output decorated with code:ViewportIndex or
1511code:ViewportMaskNV, the viewport numbered zero is used by the viewport
1512transformation.
1513endif::VK_NV_viewport_array2[]
1514ifndef::VK_NV_viewport_array2[]
1515A _<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader
1516stage>>_ can: direct each primitive to one of several viewports.
1517The destination viewport for a primitive is selected by the last active
1518<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader
1519stage>> that has an output variable decorated with code:ViewportIndex.
1520The viewport transform uses the viewport corresponding to the value assigned
1521to code:ViewportIndex, and taken from an implementation-dependent vertex of
1522each primitive.
1523If code:ViewportIndex is outside the range zero to pname:viewportCount minus
1524one for a primitive, or if the last active
1525<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader
1526stage>> did not assign a value to code:ViewportIndex for all vertices of a
1527primitive due to flow control, the values resulting from the viewport
1528transformation of the vertices of such primitives are undefined:.
1529If the last <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization
1530shader stage>> does not have an output decorated with code:ViewportIndex,
1531the viewport numbered zero is used by the viewport transformation.
1532endif::VK_NV_viewport_array2[]
1533endif::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[]
1534
1535A single vertex can: be used in more than one individual primitive, in
1536primitives such as ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP.
1537In this case, the viewport transformation is applied separately for each
1538primitive.
1539
1540[open,refpage='vkCmdSetViewport',desc='Set the viewport dynamically for a command buffer',type='protos']
1541--
1542To <<pipelines-dynamic-state, dynamically set>> the viewport transformation
1543parameters, call:
1544
1545include::{generated}/api/protos/vkCmdSetViewport.adoc[]
1546
1547  * pname:commandBuffer is the command buffer into which the command will be
1548    recorded.
1549  * pname:firstViewport is the index of the first viewport whose parameters
1550    are updated by the command.
1551  * pname:viewportCount is the number of viewports whose parameters are
1552    updated by the command.
1553  * pname:pViewports is a pointer to an array of slink:VkViewport structures
1554    specifying viewport parameters.
1555
1556This command sets the viewport transformation parameters state for
1557subsequent drawing commands when the graphics pipeline is created with
1558ename:VK_DYNAMIC_STATE_VIEWPORT set in
1559slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
1560Otherwise, this state is specified by the
1561sname:VkPipelineViewportStateCreateInfo::pname:pViewports values used to
1562create the currently active pipeline.
1563
1564The viewport parameters taken from element [eq]#i# of pname:pViewports
1565replace the current state for the viewport index [eq]#pname:firstViewport
1566{plus} i#, for [eq]#i# in [eq]#[0, pname:viewportCount)#.
1567
1568.Valid Usage
1569****
1570  * [[VUID-vkCmdSetViewport-firstViewport-01223]]
1571    The sum of pname:firstViewport and pname:viewportCount must: be between
1572    `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive
1573  * [[VUID-vkCmdSetViewport-firstViewport-01224]]
1574    If the <<features-multiViewport, pname:multiViewport>> feature is not
1575    enabled, pname:firstViewport must: be `0`
1576  * [[VUID-vkCmdSetViewport-viewportCount-01225]]
1577    If the <<features-multiViewport, pname:multiViewport>> feature is not
1578    enabled, pname:viewportCount must: be `1`
1579ifdef::VK_NV_inherited_viewport_scissor[]
1580  * [[VUID-vkCmdSetViewport-commandBuffer-04821]]
1581    pname:commandBuffer must: not have
1582    slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D
1583    enabled
1584endif::VK_NV_inherited_viewport_scissor[]
1585****
1586
1587include::{generated}/validity/protos/vkCmdSetViewport.adoc[]
1588--
1589
1590Both slink:VkPipelineViewportStateCreateInfo and flink:vkCmdSetViewport use
1591sname:VkViewport to set the viewport transformation parameters.
1592
1593[open,refpage='VkViewport',desc='Structure specifying a viewport',type='structs']
1594--
1595The sname:VkViewport structure is defined as:
1596
1597include::{generated}/api/structs/VkViewport.adoc[]
1598
1599  * pname:x and pname:y are the viewport's upper left corner [eq]#(x,y)#.
1600  * pname:width and pname:height are the viewport's width and height,
1601    respectively.
1602  * pname:minDepth and pname:maxDepth are the depth range for the viewport.
1603
1604[NOTE]
1605.Note
1606====
1607Despite their names, pname:minDepth can: be less than, equal to, or greater
1608than pname:maxDepth.
1609====
1610
1611The framebuffer depth coordinate [eq]#pname:z~f~# may: be represented using
1612either a fixed-point or floating-point representation.
1613However, a floating-point representation must: be used if the depth/stencil
1614attachment has a floating-point depth component.
1615If an [eq]#m#-bit fixed-point representation is used, we assume that it
1616represents each value latexmath:[\frac{k}{2^m - 1}], where [eq]#k {elem} {
16170, 1, ..., 2^m^-1 }#, as [eq]#k# (e.g. 1.0 is represented in binary as a
1618string of all ones).
1619
1620The viewport parameters shown in the above equations are found from these
1621values as
1622
1623  {empty}:: [eq]#o~x~ = pname:x {plus} pname:width / 2#
1624  {empty}:: [eq]#o~y~ = pname:y {plus} pname:height / 2#
1625  {empty}:: [eq]#o~z~ = pname:minDepth#
1626ifdef::VK_EXT_depth_clip_control[]
1627            (or [eq]#(pname:maxDepth + pname:minDepth) / 2# if
1628            slink:VkPipelineViewportDepthClipControlCreateInfoEXT::pname:negativeOneToOne
1629            is ename:VK_TRUE)
1630endif::VK_EXT_depth_clip_control[]
1631  {empty}:: [eq]#p~x~ = pname:width#
1632  {empty}:: [eq]#p~y~ = pname:height#
1633  {empty}:: [eq]#p~z~ = pname:maxDepth - pname:minDepth#
1634ifdef::VK_EXT_depth_clip_control[]
1635            (or [eq]#(pname:maxDepth - pname:minDepth) / 2# if
1636            slink:VkPipelineViewportDepthClipControlCreateInfoEXT::pname:negativeOneToOne
1637            is ename:VK_TRUE)
1638endif::VK_EXT_depth_clip_control[]
1639
1640ifdef::VK_QCOM_render_pass_transform[]
1641If a render pass transform is enabled, the values [eq]#(p~x~,p~y~)# and
1642[eq]#(o~x~, o~y~)# defining the viewport are transformed as described in
1643<<vertexpostproc-renderpass-transform, render pass transform>> before
1644participating in the viewport transform.
1645endif::VK_QCOM_render_pass_transform[]
1646
1647ifdef::VK_VERSION_1_1,VK_KHR_maintenance1[]
1648The application can: specify a negative term for pname:height, which has the
1649effect of negating the y coordinate in clip space before performing the
1650transform.
1651When using a negative pname:height, the application should: also adjust the
1652pname:y value to point to the lower left corner of the viewport instead of
1653the upper left corner.
1654Using the negative pname:height allows the application to avoid having to
1655negate the y component of the code:Position output from the last
1656<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader
1657stage>>.
1658endif::VK_VERSION_1_1,VK_KHR_maintenance1[]
1659
1660The width and height of the <<limits-maxViewportDimensions,
1661implementation-dependent maximum viewport dimensions>> must: be greater than
1662or equal to the width and height of the largest image which can: be created
1663and attached to a framebuffer.
1664
1665The floating-point viewport bounds are represented with an
1666<<limits-viewportSubPixelBits, implementation-dependent precision>>.
1667
1668.Valid Usage
1669****
1670  * [[VUID-VkViewport-width-01770]]
1671    pname:width must: be greater than `0.0`
1672  * [[VUID-VkViewport-width-01771]]
1673    pname:width must: be less than or equal to
1674    sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[0]
1675ifndef::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[]
1676  * [[VUID-VkViewport-height-01772]]
1677    pname:height must: be greater than `0.0`
1678endif::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[]
1679  * [[VUID-VkViewport-height-01773]]
1680    The absolute value of pname:height must: be less than or equal to
1681    sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[1]
1682  * [[VUID-VkViewport-x-01774]]
1683    pname:x must: be greater than or equal to pname:viewportBoundsRange[0]
1684  * [[VUID-VkViewport-x-01232]]
1685    [eq]#(pname:x {plus} pname:width)# must: be less than or equal to
1686    pname:viewportBoundsRange[1]
1687  * [[VUID-VkViewport-y-01775]]
1688    pname:y must: be greater than or equal to pname:viewportBoundsRange[0]
1689ifdef::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[]
1690  * [[VUID-VkViewport-y-01776]]
1691    pname:y must: be less than or equal to pname:viewportBoundsRange[1]
1692  * [[VUID-VkViewport-y-01777]]
1693    [eq]#(pname:y {plus} pname:height)# must: be greater than or equal to
1694    pname:viewportBoundsRange[0]
1695endif::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[]
1696  * [[VUID-VkViewport-y-01233]]
1697    [eq]#(pname:y {plus} pname:height)# must: be less than or equal to
1698    pname:viewportBoundsRange[1]
1699ifdef::VK_EXT_depth_range_unrestricted[]
1700  * [[VUID-VkViewport-minDepth-01234]]
1701    Unless `apiext:VK_EXT_depth_range_unrestricted` extension is enabled
1702    pname:minDepth must: be between `0.0` and `1.0`, inclusive
1703endif::VK_EXT_depth_range_unrestricted[]
1704ifndef::VK_EXT_depth_range_unrestricted[]
1705  * [[VUID-VkViewport-minDepth-02540]]
1706    pname:minDepth must: be between `0.0` and `1.0`, inclusive
1707endif::VK_EXT_depth_range_unrestricted[]
1708ifdef::VK_EXT_depth_range_unrestricted[]
1709  * [[VUID-VkViewport-maxDepth-01235]]
1710    Unless `apiext:VK_EXT_depth_range_unrestricted` extension is enabled
1711    pname:maxDepth must: be between `0.0` and `1.0`, inclusive
1712endif::VK_EXT_depth_range_unrestricted[]
1713ifndef::VK_EXT_depth_range_unrestricted[]
1714  * [[VUID-VkViewport-maxDepth-02541]]
1715    pname:maxDepth must: be between `0.0` and `1.0`, inclusive
1716endif::VK_EXT_depth_range_unrestricted[]
1717****
1718
1719include::{generated}/validity/structs/VkViewport.adoc[]
1720--
1721