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