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