1// Copyright 2015-2021 The Khronos Group, Inc. 2// 3// SPDX-License-Identifier: CC-BY-4.0 4 5[[vertexpostproc]] 6= Fixed-Function Vertex Post-Processing 7 8After <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 9stages>>, the following fixed-function operations are applied to vertices of 10the 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<<pipeline-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<<pipeline-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 89<<features-transformFeedbackPreservesProvokingVertex,transformFeedbackPreservesProvokingVertex>> 90is not enabled, implementations 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 120<<features-transformFeedbackPreservesProvokingVertex,transformFeedbackPreservesProvokingVertex>> 121is enabled, then in addition to writing vertices with a consistent winding 122order, the vertex order must: preserve the <<vertexpostproc-flatshading, 123provoking vertex>> of each 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 137<<limits-transformFeedbackPreservesTriangleFanProvokingVertex,pname:transformFeedbackPreservesTriangleFanProvokingVertex>> 138is ename:VK_FALSE, neither <<geometry,geometry>> nor 139<<tessellation,tessellation>> shading is active, and the 140<<drawing-primitive-topologies,primitive topology>> is 141ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, then the first vertex written from 142each primitive is implementation-defined even when 143<<features-transformFeedbackPreservesProvokingVertex,transformFeedbackPreservesProvokingVertex>> 144is enabled. 145 146endif::VK_EXT_provoking_vertex[] 147 148When capturing vertices, the stride associated with each transform feedback 149buffer, as indicated by the code:XfbStride decoration, indicates the number 150of bytes of storage reserved for each vertex in the transform feedback 151buffer. 152For every vertex captured, each output attribute with a code:Offset 153decoration will be written to the storage reserved for the vertex at the 154associated transform feedback buffer. 155When writing output variables that are arrays or structures, individual 156array elements or structure members are written tightly packed in order. 157For vector types, individual components are written in order. 158For matrix types, outputs are written as an array of column vectors. 159 160If any component of an output with an assigned transform feedback offset was 161not written to by its shader, the value recorded for that component is 162undefined:. 163All components of an output variable must: be written at an offset aligned 164to the size of the component. 165The size of each component of an output variable must: be at least 32-bits. 166When capturing a vertex, any portion of the reserved storage not associated 167with an output variable with an assigned transform feedback offset will be 168unmodified. 169 170When transform feedback is inactive, no vertices are recorded. 171If there is a valid counter buffer handle and counter buffer offset in the 172pname:pCounterBuffers and pname:pCounterBufferOffsets arrays, writes to the 173corresponding transform feedback buffer will start at the byte offset 174represented by the value stored in the counter buffer location. 175 176Individual lines or triangles of a strip or fan primitive will be extracted 177and recorded separately. 178Incomplete primitives are not recorded. 179 180When using a geometry shader that emits vertices to multiple vertex streams, 181a primitive will be assembled and output for each stream when there are 182enough vertices emitted for the output primitive type. 183All outputs assigned to a given transform feedback buffer are required to 184come from a single vertex stream. 185 186The sizes of the transform feedback buffers are defined by the 187flink:vkCmdBindTransformFeedbackBuffersEXT pname:pSizes parameter for each 188of the bound buffers, or the size of the bound buffer, whichever is the 189lesser. 190If there is less space remaining in any of the transform feedback buffers 191than the size of all of the vertex data for that primitive based on the 192code:XfbStride for that code:XfbBuffer then no vertex data of that primitive 193is recorded in any transform feedback buffer, and the value for the number 194of primitives written in the corresponding 195ename:VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT query for all transform 196feedback buffers is no longer incremented. 197 198Any outputs made to a code:XfbBuffer that is not bound to a transform 199feedback buffer is ignored. 200 201[open,refpage='vkCmdBindTransformFeedbackBuffersEXT',desc='Bind transform feedback buffers to a command buffer',type='protos'] 202-- 203To bind transform feedback buffers to a command buffer for use in subsequent 204drawing commands, call: 205 206include::{generated}/api/protos/vkCmdBindTransformFeedbackBuffersEXT.txt[] 207 208 * pname:commandBuffer is the command buffer into which the command is 209 recorded. 210 * pname:firstBinding is the index of the first transform feedback binding 211 whose state is updated by the command. 212 * pname:bindingCount is the number of transform feedback bindings whose 213 state is updated by the command. 214 * pname:pBuffers is a pointer to an array of buffer handles. 215 * pname:pOffsets is a pointer to an array of buffer offsets. 216 * pname:pSizes is `NULL` or a pointer to an array of basetype:VkDeviceSize 217 buffer sizes, specifying the maximum number of bytes to capture to the 218 corresponding transform feedback buffer. 219 If pname:pSizes is `NULL`, or the value of the pname:pSizes array 220 element is ename:VK_WHOLE_SIZE, then the maximum number of bytes 221 captured will be the size of the corresponding buffer minus the buffer 222 offset. 223 224The values taken from elements [eq]#i# of pname:pBuffers, pname:pOffsets and 225pname:pSizes replace the current state for the transform feedback binding 226[eq]#pname:firstBinding {plus} i#, for [eq]#i# in [eq]#[0, 227pname:bindingCount)#. 228The transform feedback binding is updated to start at the offset indicated 229by pname:pOffsets[i] from the start of the buffer pname:pBuffers[i]. 230 231.Valid Usage 232**** 233 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-transformFeedback-02355]] 234 sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:transformFeedback 235 must: be enabled 236 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02356]] 237 pname:firstBinding must: be less than 238 sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers 239 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357]] 240 The sum of pname:firstBinding and pname:bindingCount must: be less than 241 or equal to 242 sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers 243 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02358]] 244 All elements of pname:pOffsets must: be less than the size of the 245 corresponding element in pname:pBuffers 246 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02359]] 247 All elements of pname:pOffsets must: be a multiple of 4 248 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02360]] 249 All elements of pname:pBuffers must: have been created with the 250 ename:VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT flag 251 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pSize-02361]] 252 If the optional pname:pSize array is specified, each element of 253 pname:pSizes must: either be ename:VK_WHOLE_SIZE, or be less than or 254 equal to 255 sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBufferSize 256 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pSizes-02362]] 257 All elements of pname:pSizes must: be either ename:VK_WHOLE_SIZE, or 258 less than or equal to the size of the corresponding buffer in 259 pname:pBuffers 260 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363]] 261 All elements of pname:pOffsets plus pname:pSizes, where the 262 pname:pSizes, element is not ename:VK_WHOLE_SIZE, must: be less than or 263 equal to the size of the corresponding buffer in pname:pBuffers 264 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02364]] 265 Each element of pname:pBuffers that is non-sparse must: be bound 266 completely and contiguously to a single sname:VkDeviceMemory object 267 * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-None-02365]] 268 Transform feedback must: not be active when the 269 fname:vkCmdBindTransformFeedbackBuffersEXT command is recorded 270**** 271 272include::{generated}/validity/protos/vkCmdBindTransformFeedbackBuffersEXT.txt[] 273-- 274 275[open,refpage='vkCmdBeginTransformFeedbackEXT',desc='Make transform feedback active in the command buffer',type='protos'] 276-- 277Transform feedback for specific transform feedback buffers is made active by 278calling: 279 280include::{generated}/api/protos/vkCmdBeginTransformFeedbackEXT.txt[] 281 282 * pname:commandBuffer is the command buffer into which the command is 283 recorded. 284 * pname:firstCounterBuffer is the index of the first transform feedback 285 buffer corresponding to pname:pCounterBuffers[0] and 286 pname:pCounterBufferOffsets[0]. 287 * pname:counterBufferCount is the size of the pname:pCounterBuffers and 288 pname:pCounterBufferOffsets arrays. 289 * pname:pCounterBuffers is `NULL` or a pointer to an array of 290 slink:VkBuffer handles to counter buffers. 291 Each buffer contains a 4 byte integer value representing the byte offset 292 from the start of the corresponding transform feedback buffer from where 293 to start capturing vertex data. 294 If the byte offset stored to the counter buffer location was done using 295 flink:vkCmdEndTransformFeedbackEXT it can be used to resume transform 296 feedback from the previous location. 297 If pname:pCounterBuffers is `NULL`, then transform feedback will start 298 capturing vertex data to byte offset zero in all bound transform 299 feedback buffers. 300 For each element of pname:pCounterBuffers that is dlink:VK_NULL_HANDLE, 301 transform feedback will start capturing vertex data to byte zero in the 302 corresponding bound transform feedback buffer. 303 * pname:pCounterBufferOffsets is `NULL` or a pointer to an array of 304 basetype:VkDeviceSize values specifying offsets within each of the 305 pname:pCounterBuffers where the counter values were previously written. 306 The location in each counter buffer at these offsets must: be large 307 enough to contain 4 bytes of data. 308 This data is the number of bytes captured by the previous transform 309 feedback to this buffer. 310 If pname:pCounterBufferOffsets is `NULL`, then it is assumed the offsets 311 are zero. 312 313The active transform feedback buffers will capture primitives emitted from 314the corresponding code:XfbBuffer in the bound graphics pipeline. 315Any code:XfbBuffer emitted that does not output to an active transform 316feedback buffer will not be captured. 317 318.Valid Usage 319**** 320 * [[VUID-vkCmdBeginTransformFeedbackEXT-transformFeedback-02366]] 321 sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:transformFeedback 322 must: be enabled 323 * [[VUID-vkCmdBeginTransformFeedbackEXT-None-02367]] 324 Transform feedback must: not be active 325 * [[VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02368]] 326 pname:firstCounterBuffer must: be less than 327 sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers 328 * [[VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369]] 329 The sum of pname:firstCounterBuffer and pname:counterBufferCount must: 330 be less than or equal to 331 sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers 332 * [[VUID-vkCmdBeginTransformFeedbackEXT-counterBufferCount-02607]] 333 If pname:counterBufferCount is not `0`, and pname:pCounterBuffers is not 334 `NULL`, pname:pCounterBuffers must: be a valid pointer to an array of 335 pname:counterBufferCount sname:VkBuffer handles that are either valid or 336 dlink:VK_NULL_HANDLE 337 * [[VUID-vkCmdBeginTransformFeedbackEXT-pCounterBufferOffsets-02370]] 338 For each buffer handle in the array, if it is not dlink:VK_NULL_HANDLE 339 it must: reference a buffer large enough to hold 4 bytes at the 340 corresponding offset from the pname:pCounterBufferOffsets array 341 * [[VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffer-02371]] 342 If pname:pCounterBuffer is `NULL`, then pname:pCounterBufferOffsets 343 must: also be `NULL` 344 * [[VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffers-02372]] 345 For each buffer handle in the pname:pCounterBuffers array that is not 346 dlink:VK_NULL_HANDLE it must: have been created with a pname:usage value 347 containing 348 ename:VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT 349 * [[VUID-vkCmdBeginTransformFeedbackEXT-None-06233]] 350 A valid graphics pipeline must: be bound to 351 ename:VK_PIPELINE_BIND_POINT_GRAPHICS 352 * [[VUID-vkCmdBeginTransformFeedbackEXT-None-04128]] 353 The last <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization 354 shader stage>> of the bound graphics pipeline must: have been declared 355 with the 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.txt[] 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.txt[] 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.txt[] 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.txt[] 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.txt[] 468-- 469 470[open,refpage='VkPipelineViewportSwizzleStateCreateFlagsNV',desc='Reserved for future use',type='flags'] 471-- 472include::{generated}/api/flags/VkPipelineViewportSwizzleStateCreateFlagsNV.txt[] 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 483Each viewport specified from 0 to pname:viewportCount - 1 has its x,y,z,w 484swizzle state set to the corresponding pname:x, pname:y, pname:z and pname:w 485in the slink:VkViewportSwizzleNV structure. 486Each component is of type elink:VkViewportCoordinateSwizzleNV, which 487determines the type of swizzle for that component. 488The value of pname:x computes the new x component of the position as: 489 490[source,c] 491--------------------------------------------------- 492if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV) x' = x; 493if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV) x' = -x; 494if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV) x' = y; 495if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV) x' = -y; 496if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV) x' = z; 497if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV) x' = -z; 498if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV) x' = w; 499if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV) x' = -w; 500--------------------------------------------------- 501 502Similar selections are performed for the pname:y, pname:z, and pname:w 503coordinates. 504This swizzling is applied before clipping and perspective divide. 505If the swizzle for an active viewport index is not specified, the swizzle 506for pname:x is ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, pname:y 507is ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV, pname:z is 508ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV and pname:w is 509ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV. 510 511Viewport swizzle parameters are specified by setting the pname:pNext pointer 512of sname:VkGraphicsPipelineCreateInfo to point to a 513sname:VkPipelineViewportSwizzleStateCreateInfoNV structure. 514slink:VkPipelineViewportSwizzleStateCreateInfoNV uses 515sname:VkViewportSwizzleNV to set the viewport swizzle parameters. 516 517[open,refpage='VkViewportSwizzleNV',desc='Structure specifying a viewport swizzle',type='structs'] 518-- 519The sname:VkViewportSwizzleNV structure is defined as: 520 521include::{generated}/api/structs/VkViewportSwizzleNV.txt[] 522 523 * pname:x is a elink:VkViewportCoordinateSwizzleNV value specifying the 524 swizzle operation to apply to the x component of the primitive 525 * pname:y is a elink:VkViewportCoordinateSwizzleNV value specifying the 526 swizzle operation to apply to the y component of the primitive 527 * pname:z is a elink:VkViewportCoordinateSwizzleNV value specifying the 528 swizzle operation to apply to the z component of the primitive 529 * pname:w is a elink:VkViewportCoordinateSwizzleNV value specifying the 530 swizzle operation to apply to the w component of the primitive 531 532include::{generated}/validity/structs/VkViewportSwizzleNV.txt[] 533-- 534 535[open,refpage='VkViewportCoordinateSwizzleNV',desc='Specify how a viewport coordinate is swizzled',type='enums'] 536-- 537Possible values of the slink:VkViewportSwizzleNV::pname:x, pname:y, pname:z, 538and pname:w members, specifying swizzling of the corresponding components of 539primitives, are: 540 541include::{generated}/api/enums/VkViewportCoordinateSwizzleNV.txt[] 542 543These values are described in detail in <<vertexpostproc-viewport-swizzle, 544Viewport Swizzle>>. 545-- 546endif::VK_NV_viewport_swizzle[] 547 548 549[[vertexpostproc-flatshading]] 550== Flat Shading 551 552_Flat shading_ a vertex output attribute means to assign all vertices of the 553primitive the same value for that output. 554The output values assigned are those of the _provoking vertex_ of the 555primitive. 556Flat shading is applied to those vertex attributes that 557<<interfaces-iointerfaces-matching,match>> fragment input attributes which 558are decorated as code:Flat. 559 560If neither <<geometry,geometry>> nor <<tessellation,tessellation shading>> 561is active, the provoking vertex is determined by the 562<<drawing-primitive-topologies, primitive topology>> defined by 563slink:VkPipelineInputAssemblyStateCreateInfo:pname:topology used to execute 564the <<drawing,drawing command>>. 565 566If <<geometry,geometry shading>> is active, the provoking vertex is 567determined by the <<drawing-primitive-topologies, primitive topology>> 568defined by the <<drawing-point-lists, code:OutputPoints>>, 569<<drawing-line-strips, code:OutputLineStrips>>, or 570<<drawing-triangle-strips, code:OutputTriangleStrips>> execution mode. 571 572If <<tessellation,tessellation shading>> is active but <<geometry,geometry 573shading>> is not, the provoking vertex may: be any of the vertices in each 574primitive. 575 576ifdef::VK_EXT_provoking_vertex[] 577[open,refpage='VkPipelineRasterizationProvokingVertexStateCreateInfoEXT',desc='Structure specifying provoking vertex mode used by a graphics pipeline',type='structs'] 578-- 579For a given primitive topology, the pipeline's provoking vertex mode 580determines which vertex is the provoking vertex. 581To specify the provoking vertex mode, include a 582sname:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT structure in 583the slink:VkPipelineRasterizationStateCreateInfo::pname:pNext chain when 584creating the pipeline. 585 586The sname:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT structure 587is defined as: 588 589include::{generated}/api/structs/VkPipelineRasterizationProvokingVertexStateCreateInfoEXT.txt[] 590 591 * pname:sType is the type of this structure. 592 * pname:pNext is `NULL` or a pointer to a structure extending this 593 structure. 594 * pname:provokingVertexMode is a elink:VkProvokingVertexModeEXT value 595 selecting the provoking vertex mode. 596 597If this struct is not provided when creating the pipeline, the pipeline will 598use the ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT mode. 599 600If the 601<<limits-provokingVertexModePerPipeline,provokingVertexModePerPipeline>> 602limit is ename:VK_FALSE, then all pipelines bound within a render pass 603instance must: have the same pname:provokingVertexMode. 604 605.Valid Usage 606**** 607 * [[VUID-VkPipelineRasterizationProvokingVertexStateCreateInfoEXT-provokingVertexMode-04883]] 608 If pname:provokingVertexMode is 609 ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, then the 610 <<features-provokingVertexLast,provokingVertexLast>> feature must: be 611 enabled 612**** 613 614include::{generated}/validity/structs/VkPipelineRasterizationProvokingVertexStateCreateInfoEXT.txt[] 615-- 616 617[open,refpage='VkProvokingVertexModeEXT',desc='Specify which vertex in a primitive is the provoking vertex',type='enums'] 618-- 619Possible values of 620slink:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::pname:provokingVertexMode 621are: 622 623include::{generated}/api/enums/VkProvokingVertexModeEXT.txt[] 624 625 * ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT specifies that the 626 provoking vertex is the first non-adjacency vertex in the list of 627 vertices used by a primitive. 628 * ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT specifies that the 629 provoking vertex is the last non-adjacency vertex in the list of 630 vertices used by a primitive. 631 632These modes are described more precisely in 633<<drawing-primitive-topologies,Primitive Topologies>>. 634-- 635endif::VK_EXT_provoking_vertex[] 636 637 638[[vertexpostproc-clipping]] 639== Primitive Clipping 640 641Primitives are culled against the _cull volume_ and then clipped to the 642_clip volume_. 643In clip coordinates, the _view volume_ is defined by: 644 645[latexmath] 646++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 647\begin{array}{c} 648-w_c \leq x_c \leq w_c \\ 649-w_c \leq y_c \leq w_c \\ 6500 \leq z_c \leq w_c 651\end{array} 652++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 653 654This view volume can: be further restricted by as many as 655sname:VkPhysicalDeviceLimits::pname:maxClipDistances client-defined 656half-spaces. 657 658The cull volume is the intersection of up to 659sname:VkPhysicalDeviceLimits::pname:maxCullDistances client-defined 660half-spaces (if no client-defined cull half-spaces are enabled, culling 661against the cull volume is skipped). 662 663A shader must: write a single cull distance for each enabled cull half-space 664to elements of the code:CullDistance array. 665If the cull distance for any enabled cull half-space is negative for all of 666the vertices of the primitive under consideration, the primitive is 667discarded. 668Otherwise the primitive is clipped against the clip volume as defined below. 669 670The clip volume is the intersection of up to 671sname:VkPhysicalDeviceLimits::pname:maxClipDistances client-defined 672half-spaces with the view volume (if no client-defined clip half-spaces are 673enabled, the clip volume is the view volume). 674 675A shader must: write a single clip distance for each enabled clip half-space 676to elements of the code:ClipDistance array. 677Clip half-space [eq]#i# is then given by the set of points satisfying the 678inequality 679 680 {empty}:: [eq]#c~i~(**P**) {geq} 0# 681 682where [eq]#c~i~(**P**)# is the clip distance [eq]#i# at point [eq]#**P**#. 683For point primitives, [eq]#c~i~(**P**)# is simply the clip distance for the 684vertex in question. 685For line and triangle primitives, per-vertex clip distances are interpolated 686using a weighted mean, with weights derived according to the algorithms 687described in sections <<primsrast-lines-basic,Basic Line Segment 688Rasterization>> and <<primsrast-polygons-basic,Basic Polygon 689Rasterization>>, using the perspective interpolation equations. 690 691The number of client-defined clip and cull half-spaces that are enabled is 692determined by the explicit size of the built-in arrays code:ClipDistance and 693code:CullDistance, respectively, declared as an output in the interface of 694the entry point of the final shader stage before clipping. 695 696ifdef::VK_EXT_depth_clip_enable[] 697If slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT is present in 698the graphics pipeline state then depth clipping is disabled if 699slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT::pname:depthClipEnable 700is ename:VK_FALSE. 701Otherwise, if slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT is 702not present, depth clipping is disabled when 703slink:VkPipelineRasterizationStateCreateInfo::pname:depthClampEnable is 704ename:VK_TRUE. 705endif::VK_EXT_depth_clip_enable[] 706ifndef::VK_EXT_depth_clip_enable[] 707Depth clamping is enabled or disabled via the pname:depthClampEnable enable 708of the slink:VkPipelineRasterizationStateCreateInfo structure. 709Depth clipping is disabled when pname:depthClampEnable is ename:VK_TRUE. 710endif::VK_EXT_depth_clip_enable[] 711When depth clipping is disabled, the plane equation 712 713 {empty}:: [eq]#0 {leq} z~c~ {leq} w~c~# 714 715(see the clip volume definition above) is ignored by view volume clipping 716(effectively, there is no near or far plane clipping). 717 718If the primitive under consideration is a point or line segment, then 719clipping passes it unchanged if its vertices lie entirely within the clip 720volume. 721 722ifndef::VK_VERSION_1_1,VK_KHR_maintenance2[] 723If a point's vertex lies outside of the clip volume, the entire primitive 724may: be discarded. 725endif::VK_VERSION_1_1,VK_KHR_maintenance2[] 726 727ifdef::VK_VERSION_1_1,VK_KHR_maintenance2[] 728[open,refpage='VkPointClippingBehavior',desc='Enum specifying the point clipping behavior',type='enums'] 729-- 730Possible values of 731slink:VkPhysicalDevicePointClippingProperties::pname:pointClippingBehavior, 732specifying clipping behavior of a point primitive whose vertex lies outside 733the clip volume, are: 734 735include::{generated}/api/enums/VkPointClippingBehavior.txt[] 736 737ifdef::VK_KHR_maintenance2[] 738or the equivalent 739 740include::{generated}/api/enums/VkPointClippingBehaviorKHR.txt[] 741endif::VK_KHR_maintenance2[] 742 743 * ename:VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES specifies that the 744 primitive is discarded if the vertex lies outside any clip plane, 745 including the planes bounding the view volume. 746 * ename:VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY specifies that 747 the primitive is discarded only if the vertex lies outside any user clip 748 plane. 749-- 750endif::VK_VERSION_1_1,VK_KHR_maintenance2[] 751 752If either of a line segment's vertices lie outside of the clip volume, the 753line segment may: be clipped, with new vertex coordinates computed for each 754vertex that lies outside the clip volume. 755A clipped line segment endpoint lies on both the original line segment and 756the boundary of the clip volume. 757 758This clipping produces a value, [eq]#0 {leq} t {leq} 1#, for each clipped 759vertex. 760If the coordinates of a clipped vertex are [eq]#**P**# and the unclipped 761line segment's vertex coordinates are [eq]#**P**~1~# and [eq]#**P**~2~#, 762then [eq]#t# satisfies the following equation 763 764 {empty}:: [eq]#**P** = t **P**~1~ {plus} (1-t) **P**~2~#. 765 766[eq]#t# is used to clip vertex output attributes as described in 767<<vertexpostproc-clipping-shader-outputs,Clipping Shader Outputs>>. 768 769If the primitive is a polygon, it passes unchanged if every one of its edges 770lies entirely inside the clip volume, and is either clipped or discarded 771otherwise. 772If the edges of the polygon intersect the boundary of the clip volume, the 773intersecting edges are reconnected by new edges that lie along the boundary 774of the clip volume - in some cases requiring the introduction of new 775vertices into a polygon. 776 777If a polygon intersects an edge of the clip volume's boundary, the clipped 778polygon must: include a point on this boundary edge. 779 780Primitives rendered with user-defined half-spaces must: satisfy a 781complementarity criterion. 782Suppose a series of primitives is drawn where each vertex [eq]#i# has a 783single specified clip distance [eq]#d~i~# (or a number of similarly 784specified clip distances, if multiple half-spaces are enabled). 785Next, suppose that the same series of primitives are drawn again with each 786such clip distance replaced by [eq]#-d~i~# (and the graphics pipeline is 787otherwise the same). 788In this case, primitives must: not be missing any pixels, and pixels must: 789not be drawn twice in regions where those primitives are cut by the clip 790planes. 791 792 793[[vertexpostproc-clipping-shader-outputs]] 794== Clipping Shader Outputs 795 796Next, vertex output attributes are clipped. 797The output values associated with a vertex that lies within the clip volume 798are unaffected by clipping. 799If a primitive is clipped, however, the output values assigned to vertices 800produced by clipping are clipped. 801 802Let the output values assigned to the two vertices [eq]#**P**~1~# and 803[eq]#**P**~2~# of an unclipped edge be [eq]#**c**~1~# and [eq]#**c**~2~#. 804The value of [eq]#t# (see <<vertexpostproc-clipping,Primitive Clipping>>) 805for a clipped point [eq]#**P**# is used to obtain the output value 806associated with [eq]#**P**# as 807 808 {empty}:: [eq]#**c** = t **c**~1~ {plus} (1-t) **c**~2~#. 809 810(Multiplying an output value by a scalar means multiplying each of _x_, _y_, 811_z_, and _w_ by the scalar.) 812 813Since this computation is performed in clip space before division by 814[eq]#w~c~#, clipped output values are perspective-correct. 815 816Polygon clipping creates a clipped vertex along an edge of the clip volume's 817boundary. 818This situation is handled by noting that polygon clipping proceeds by 819clipping against one half-space at a time. 820Output value clipping is done in the same way, so that clipped points always 821occur at the intersection of polygon edges (possibly already clipped) with 822the clip volume's boundary. 823 824For vertex output attributes whose matching fragment input attributes are 825decorated with code:NoPerspective, the value of [eq]#t# used to obtain the 826output value associated with [eq]#**P**# will be adjusted to produce results 827that vary linearly in framebuffer space. 828 829Output attributes of integer or unsigned integer type must: always be flat 830shaded. 831Flat shaded attributes are constant over the primitive being rasterized (see 832<<primsrast-lines-basic,Basic Line Segment Rasterization>> and 833<<primsrast-polygons-basic,Basic Polygon Rasterization>>), and no 834interpolation is performed. 835The output value [eq]#**c**# is taken from either [eq]#**c**~1~# or 836[eq]#**c**~2~#, since flat shading has already occurred and the two values 837are identical. 838 839ifdef::VK_NV_clip_space_w_scaling[] 840include::VK_NV_clip_space_w_scaling/vertexpostproc.txt[] 841endif::VK_NV_clip_space_w_scaling[] 842 843 844[[vertexpostproc-coord-transform]] 845== Coordinate Transformations 846 847_Clip coordinates_ for a vertex result from shader execution, which yields a 848vertex coordinate code:Position. 849 850Perspective division on clip coordinates yields _normalized device 851coordinates_, followed by a _viewport_ transformation (see 852<<vertexpostproc-viewport,Controlling the Viewport>>) to convert these 853coordinates into _framebuffer coordinates_. 854 855If a vertex in clip coordinates has a position given by 856 857[latexmath] 858++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 859\left(\begin{array}{c} 860x_c \\ 861y_c \\ 862z_c \\ 863w_c 864\end{array}\right) 865++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 866 867then the vertex's normalized device coordinates are 868[latexmath] 869++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 870\left( 871 \begin{array}{c} 872 x_d \\ 873 y_d \\ 874 z_d 875 \end{array} 876\right) = 877\left( 878 \begin{array}{c} 879 \frac{x_c}{w_c} \\ 880 \frac{y_c}{w_c} \\ 881 \frac{z_c}{w_c} 882 \end{array} 883\right) 884++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 885 886 887ifdef::VK_QCOM_render_pass_transform[] 888[[vertexpostproc-renderpass-transform]] 889== Render Pass Transform 890 891A _render pass transform_ can: be enabled for render pass instances. 892The clip coordinates [eq]#(x~c~, y~c~)# that result from vertex shader 893execution are transformed by a rotation of 0, 90, 180, or 270 degrees in the 894XY plane, centered at the origin. 895 896When _Render pass transform_ is enabled, the transform applies to all 897primitives for all subpasses of the render pass. 898The transformed vertex in clip coordinates has a position given by 899 900[latexmath] 901++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 902\left( 903 \begin{array}{c} 904 x_{c_{trans}} \\ 905 y_{c_{trans}} \\ 906 z_{c_{trans}} 907 \end{array} 908\right) = 909\left( 910 \begin{array}{c} 911 x_{c} \cos \theta - y_{c} \sin \theta \\ 912 x_{c} \sin \theta + y_{c} \cos \theta \\ 913 z_c 914 \end{array} 915\right) 916++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 917 918where 919 920 * _[eq]#{theta}#_ is 0 degrees for 921 ename:VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR 922 * _[eq]#{theta}#_ is 90 degrees for 923 ename:VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR 924 * _[eq]#{theta}#_ is 180 degrees for 925 ename:VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR 926 * _[eq]#{theta}#_ is 270 degrees for 927 ename:VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR 928 929 930The transformed vertex's normalized device coordinates are 931[latexmath] 932++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 933\left( 934 \begin{array}{c} 935 x_d \\ 936 y_d \\ 937 z_d 938 \end{array} 939\right) = 940\left( 941 \begin{array}{c} 942 \frac{x_{c_{trans}}}{w_c} \\ 943 \frac{y_{c_{trans}}}{w_c} \\ 944 \frac{z_{c_{trans}}}{w_c} 945 \end{array} 946\right) 947++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 948 949 950When render pass transform is enabled for a render pass instance, the 951following additional features are enabled: 952 953 * Each slink:VkViewport specified by either 954 slink:VkPipelineViewportStateCreateInfo::pname:pViewports or 955 flink:vkCmdSetViewport will have its width/height [eq]#(p~x~, p~y~)# and 956 its center [eq]#(o~x~, o~y~)# similarly transformed by the 957 implementation. 958 * Each scissor specified by 959 slink:VkPipelineViewportStateCreateInfo::pname:pScissors or 960 flink:vkCmdSetScissor will have its [eq]#(offset~x~, offset~y~)# and 961 [eq]#(extent~x~, extent~y~)# similarly transformed by the 962 implementation. 963 * The pname:renderArea specified in 964 slink:VkCommandBufferInheritanceRenderPassTransformInfoQCOM and 965 slink:VkRenderPassBeginInfo will be similarly transformed by the 966 implementation. 967 * The [eq]#(x, y)# components of shader variables with built-in 968 decorations code:FragCoord, code:SamplePosition, or code:PointCoord will 969 be similarly transformed by the implementation. 970 * The [eq]#(x,y)# components of the code:offset operand of the 971 code:InterpolateAtOffset extended instruction will be similarly 972 transformed by the implementation. 973 * The values returned by SPIR-V <<shaders-derivative-operations, 974 derivative instructions>> code:OpDPdx, code:OpDPdy, code:OpDPdxCourse, 975 code:OpDPdyCourse, code:OpDPdxFine, code:OpDPdyFine will be similarly 976 transformed by the implementation. 977 978 979The net result of the above, is that applications can: act as if rendering 980to a framebuffer oriented with the 981slink:VkSurfaceCapabilitiesKHR::pname:currentTransform. 982In other words, applications can: act as if the presentation engine will be 983performing the transformation of the swapchain image after rendering and 984prior to presentation to the user. 985In fact, the transformation of the various items cited above are being 986handled by the implementation as the rendering takes place. 987 988endif::VK_QCOM_render_pass_transform[] 989 990 991[[vertexpostproc-viewport]] 992== Controlling the Viewport 993 994The viewport transformation is determined by the selected viewport's width 995and height in pixels, [eq]#p~x~# and [eq]#p~y~#, respectively, and its 996center [eq]#(o~x~, o~y~)# (also in pixels), as well as its depth range min 997and max determining a depth range scale value [eq]#p~z~# and a depth range 998bias value [eq]#o~z~# (defined below). 999The vertex's framebuffer coordinates [eq]#(x~f~, y~f~, z~f~)# are given by 1000 1001 {empty}:: [eq]#x~f~ = (p~x~ / 2) x~d~ {plus} o~x~# 1002 {empty}:: [eq]#y~f~ = (p~y~ / 2) y~d~ {plus} o~y~# 1003 {empty}:: [eq]#z~f~ = p~z~ {times} z~d~ {plus} o~z~# 1004 1005Multiple viewports are available, numbered zero up to 1006sname:VkPhysicalDeviceLimits::pname:maxViewports minus one. 1007The number of viewports used by a pipeline is controlled by the 1008pname:viewportCount member of the sname:VkPipelineViewportStateCreateInfo 1009structure used in pipeline creation. 1010 1011[eq]#x~f~# and [eq]#y~f~# have limited precision, where the number of 1012fractional bits retained is specified by 1013sname:VkPhysicalDeviceLimits::pname:subPixelPrecisionBits. 1014ifdef::VK_EXT_line_rasterization[] 1015When rasterizing <<primsrast-lines,line segments>>, the number of fractional 1016bits is specified by 1017sname:VkPhysicalDeviceLineRasterizationPropertiesEXT::pname:lineSubPixelPrecisionBits. 1018endif::VK_EXT_line_rasterization[] 1019 1020[open,refpage='VkPipelineViewportStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline viewport state',type='structs'] 1021-- 1022The sname:VkPipelineViewportStateCreateInfo structure is defined as: 1023 1024include::{generated}/api/structs/VkPipelineViewportStateCreateInfo.txt[] 1025 1026 * pname:sType is the type of this structure. 1027 * pname:pNext is `NULL` or a pointer to a structure extending this 1028 structure. 1029 * pname:flags is reserved for future use. 1030 * pname:viewportCount is the number of viewports used by the pipeline. 1031 * pname:pViewports is a pointer to an array of slink:VkViewport 1032 structures, defining the viewport transforms. 1033 If the viewport state is dynamic, this member is ignored. 1034 * pname:scissorCount is the number of <<fragops-scissor,scissors>> and 1035 must: match the number of viewports. 1036 * pname:pScissors is a pointer to an array of slink:VkRect2D structures 1037 defining the rectangular bounds of the scissor for the corresponding 1038 viewport. 1039 If the scissor state is dynamic, this member is ignored. 1040 1041.Valid Usage 1042**** 1043 * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216]] 1044 If the <<features-multiViewport,multiple viewports>> feature is not 1045 enabled, pname:viewportCount must: not be greater than `1` 1046 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217]] 1047 If the <<features-multiViewport,multiple viewports>> feature is not 1048 enabled, pname:scissorCount must: not be greater than `1` 1049 * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218]] 1050 pname:viewportCount must: be less than or equal to 1051 sname:VkPhysicalDeviceLimits::pname:maxViewports 1052 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219]] 1053 pname:scissorCount must: be less than or equal to 1054 sname:VkPhysicalDeviceLimits::pname:maxViewports 1055ifndef::VK_EXT_extended_dynamic_state[] 1056 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220]] 1057 pname:scissorCount and pname:viewportCount must: be identical 1058endif::VK_EXT_extended_dynamic_state[] 1059 * [[VUID-VkPipelineViewportStateCreateInfo-x-02821]] 1060 The pname:x and pname:y members of pname:offset member of any element of 1061 pname:pScissors must: be greater than or equal to `0` 1062 * [[VUID-VkPipelineViewportStateCreateInfo-offset-02822]] 1063 Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# must: not 1064 cause a signed integer addition overflow for any element of 1065 pname:pScissors 1066 * [[VUID-VkPipelineViewportStateCreateInfo-offset-02823]] 1067 Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# must: 1068 not cause a signed integer addition overflow for any element of 1069 pname:pScissors 1070ifndef::VK_EXT_extended_dynamic_state[] 1071 * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength]] 1072 pname:viewportCount must: be greater than `0` 1073 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength]] 1074 pname:scissorCount must: be greater than `0` 1075endif::VK_EXT_extended_dynamic_state[] 1076ifdef::VK_EXT_extended_dynamic_state[] 1077 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-04134]] 1078 If the graphics pipeline is being created without 1079 ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT and 1080 ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT set then 1081 pname:scissorCount and pname:viewportCount must: be identical 1082 * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135]] 1083 If the graphics pipeline is being created with 1084 ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT set then 1085 pname:viewportCount must: be `0`, otherwise it must: be greater than `0` 1086 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136]] 1087 If the graphics pipeline is being created with 1088 ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT set then 1089 pname:scissorCount must: be `0`, otherwise it must: be greater than `0` 1090endif::VK_EXT_extended_dynamic_state[] 1091ifdef::VK_NV_clip_space_w_scaling[] 1092 * [[VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726]] 1093 If the pname:viewportWScalingEnable member of a 1094 slink:VkPipelineViewportWScalingStateCreateInfoNV structure included in 1095 the pname:pNext chain is ename:VK_TRUE, the pname:viewportCount member 1096 of the slink:VkPipelineViewportWScalingStateCreateInfoNV structure must: 1097 be greater than or equal to 1098 slink:VkPipelineViewportStateCreateInfo::pname:viewportCount 1099endif::VK_NV_clip_space_w_scaling[] 1100**** 1101 1102include::{generated}/validity/structs/VkPipelineViewportStateCreateInfo.txt[] 1103-- 1104 1105ifdef::VK_EXT_extended_dynamic_state[] 1106[open,refpage='vkCmdSetViewportWithCountEXT',desc='Set the viewport count and viewports dynamically for a command buffer',type='protos'] 1107-- 1108To <<pipelines-dynamic-state, dynamically set>> the viewport count and 1109viewports, call: 1110 1111include::{generated}/api/protos/vkCmdSetViewportWithCountEXT.txt[] 1112 1113 * pname:commandBuffer is the command buffer into which the command will be 1114 recorded. 1115 * pname:viewportCount specifies the viewport count. 1116 * pname:pViewports specifies the viewports to use for drawing. 1117 1118This command sets the viewport count and viewports state for subsequent 1119drawing commands when the graphics pipeline is created with 1120ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT set in 1121slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. 1122Otherwise, this state is specified by the corresponding 1123slink:VkPipelineViewportStateCreateInfo::pname:viewportCount and 1124pname:pViewports values used to create the currently active pipeline. 1125 1126.Valid Usage 1127**** 1128 * [[VUID-vkCmdSetViewportWithCountEXT-None-03393]] 1129 The <<features-extendedDynamicState, extendedDynamicState>> feature 1130 must: be enabled 1131 * [[VUID-vkCmdSetViewportWithCountEXT-viewportCount-03394]] 1132 pname:viewportCount must: be between `1` and 1133 sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive 1134 * [[VUID-vkCmdSetViewportWithCountEXT-viewportCount-03395]] 1135 If the <<features-multiViewport,multiple viewports>> feature is not 1136 enabled, pname:viewportCount must: be `1` 1137ifdef::VK_NV_inherited_viewport_scissor[] 1138 * [[VUID-vkCmdSetViewportWithCountEXT-commandBuffer-04819]] 1139 pname:commandBuffer must: not have 1140 slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D 1141 enabled 1142endif::VK_NV_inherited_viewport_scissor[] 1143**** 1144 1145include::{generated}/validity/protos/vkCmdSetViewportWithCountEXT.txt[] 1146-- 1147 1148[open,refpage='vkCmdSetScissorWithCountEXT',desc='Set the scissor count and scissor rectangular bounds dynamically for a command buffer',type='protos'] 1149-- 1150To <<pipelines-dynamic-state, dynamically set>> the scissor count and 1151scissor rectangular bounds, call: 1152 1153include::{generated}/api/protos/vkCmdSetScissorWithCountEXT.txt[] 1154 1155 * pname:commandBuffer is the command buffer into which the command will be 1156 recorded. 1157 * pname:scissorCount specifies the scissor count. 1158 * pname:pScissors specifies the scissors to use for drawing. 1159 1160This command sets the scissor count and scissor rectangular bounds state for 1161subsequence drawing commands when the graphics pipeline is created with 1162ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT set in 1163slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. 1164Otherwise, this state is specified by the corresponding 1165slink:VkPipelineViewportStateCreateInfo::pname:scissorCount and 1166pname:pScissors values used to create the currently active pipeline. 1167 1168.Valid Usage 1169**** 1170 * [[VUID-vkCmdSetScissorWithCountEXT-None-03396]] 1171 The <<features-extendedDynamicState, extendedDynamicState>> feature 1172 must: be enabled 1173 * [[VUID-vkCmdSetScissorWithCountEXT-scissorCount-03397]] 1174 pname:scissorCount must: be between `1` and 1175 sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive 1176 * [[VUID-vkCmdSetScissorWithCountEXT-scissorCount-03398]] 1177 If the <<features-multiViewport,multiple viewports>> feature is not 1178 enabled, pname:scissorCount must: be `1` 1179 * [[VUID-vkCmdSetScissorWithCountEXT-x-03399]] 1180 The pname:x and pname:y members of pname:offset member of any element of 1181 pname:pScissors must: be greater than or equal to `0` 1182 * [[VUID-vkCmdSetScissorWithCountEXT-offset-03400]] 1183 Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# must: not 1184 cause a signed integer addition overflow for any element of 1185 pname:pScissors 1186 * [[VUID-vkCmdSetScissorWithCountEXT-offset-03401]] 1187 Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# must: 1188 not cause a signed integer addition overflow for any element of 1189 pname:pScissors 1190ifdef::VK_NV_inherited_viewport_scissor[] 1191 * [[VUID-vkCmdSetScissorWithCountEXT-commandBuffer-04820]] 1192 pname:commandBuffer must: not have 1193 slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D 1194 enabled 1195endif::VK_NV_inherited_viewport_scissor[] 1196**** 1197 1198include::{generated}/validity/protos/vkCmdSetScissorWithCountEXT.txt[] 1199-- 1200endif::VK_EXT_extended_dynamic_state[] 1201 1202[open,refpage='VkPipelineViewportStateCreateFlags',desc='Reserved for future use',type='flags'] 1203-- 1204include::{generated}/api/flags/VkPipelineViewportStateCreateFlags.txt[] 1205 1206tname:VkPipelineViewportStateCreateFlags is a bitmask type for setting a 1207mask, but is currently reserved for future use. 1208-- 1209 1210ifndef::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] 1211If a geometry shader is active and has an output variable decorated with 1212code:ViewportIndex, the viewport transformation uses the viewport 1213corresponding to the value assigned to code:ViewportIndex taken from an 1214implementation-dependent vertex of each primitive. 1215If code:ViewportIndex is outside the range zero to pname:viewportCount minus 1216one for a primitive, or if the geometry shader did not assign a value to 1217code:ViewportIndex for all vertices of a primitive due to flow control, the 1218values resulting from the viewport transformation of the vertices of such 1219primitives are undefined:. 1220If no geometry shader is active, or if the geometry shader does not have an 1221output decorated with code:ViewportIndex, the viewport numbered zero is used 1222by the viewport transformation. 1223endif::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] 1224 1225ifdef::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] 1226ifdef::VK_NV_viewport_array2[] 1227A _<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1228stage>>_ can: direct each primitive to zero or more viewports. 1229The destination viewports for a primitive are selected by the last active 1230<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1231stage>> that has an output variable decorated with code:ViewportIndex 1232(selecting a single viewport) or code:ViewportMaskNV (selecting multiple 1233viewports). 1234The viewport transform uses the viewport corresponding to either the value 1235assigned to code:ViewportIndex or one of the bits set in 1236code:ViewportMaskNV, and taken from an implementation-dependent vertex of 1237each primitive. 1238If code:ViewportIndex or any of the bits in code:ViewportMaskNV are outside 1239the range zero to pname:viewportCount minus one for a primitive, or if the 1240last active <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization 1241shader stage>> did not assign a value to either code:ViewportIndex or 1242code:ViewportMaskNV for all vertices of a primitive due to flow control, the 1243values resulting from the viewport transformation of the vertices of such 1244primitives are undefined:. 1245If the last <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization 1246shader stage>> does not have an output decorated with code:ViewportIndex or 1247code:ViewportMaskNV, the viewport numbered zero is used by the viewport 1248transformation. 1249endif::VK_NV_viewport_array2[] 1250ifndef::VK_NV_viewport_array2[] 1251A _<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1252stage>>_ can: direct each primitive to one of several viewports. 1253The destination viewport for a primitive is selected by the last active 1254<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1255stage>> that has an output variable decorated with code:ViewportIndex. 1256The viewport transform uses the viewport corresponding to the value assigned 1257to code:ViewportIndex, and taken from an implementation-dependent vertex of 1258each primitive. 1259If code:ViewportIndex is outside the range zero to pname:viewportCount minus 1260one for a primitive, or if the last active 1261<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1262stage>> did not assign a value to code:ViewportIndex for all vertices of a 1263primitive due to flow control, the values resulting from the viewport 1264transformation of the vertices of such primitives are undefined:. 1265If the last <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization 1266shader stage>> does not have an output decorated with code:ViewportIndex, 1267the viewport numbered zero is used by the viewport transformation. 1268endif::VK_NV_viewport_array2[] 1269endif::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] 1270 1271A single vertex can: be used in more than one individual primitive, in 1272primitives such as ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP. 1273In this case, the viewport transformation is applied separately for each 1274primitive. 1275 1276[open,refpage='vkCmdSetViewport',desc='Set the viewport dynamically for a command buffer',type='protos'] 1277-- 1278To <<pipelines-dynamic-state, dynamically set>> the viewport transformation 1279parameters, call: 1280 1281include::{generated}/api/protos/vkCmdSetViewport.txt[] 1282 1283 * pname:commandBuffer is the command buffer into which the command will be 1284 recorded. 1285 * pname:firstViewport is the index of the first viewport whose parameters 1286 are updated by the command. 1287 * pname:viewportCount is the number of viewports whose parameters are 1288 updated by the command. 1289 * pname:pViewports is a pointer to an array of slink:VkViewport structures 1290 specifying viewport parameters. 1291 1292This command sets the viewport transformation parameters state for 1293subsequent drawing commands when the graphics pipeline is created with 1294ename:VK_DYNAMIC_STATE_VIEWPORT set in 1295slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. 1296Otherwise, this state is specified by the 1297sname:VkPipelineViewportStateCreateInfo::pname:pViewports values used to 1298create the currently active pipeline. 1299 1300The viewport parameters taken from element [eq]#i# of pname:pViewports 1301replace the current state for the viewport index [eq]#pname:firstViewport 1302{plus} i#, for [eq]#i# in [eq]#[0, pname:viewportCount)#. 1303 1304.Valid Usage 1305**** 1306 * [[VUID-vkCmdSetViewport-firstViewport-01223]] 1307 The sum of pname:firstViewport and pname:viewportCount must: be between 1308 `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive 1309 * [[VUID-vkCmdSetViewport-firstViewport-01224]] 1310 If the <<features-multiViewport,multiple viewports>> feature is not 1311 enabled, pname:firstViewport must: be `0` 1312 * [[VUID-vkCmdSetViewport-viewportCount-01225]] 1313 If the <<features-multiViewport,multiple viewports>> feature is not 1314 enabled, pname:viewportCount must: be `1` 1315ifdef::VK_NV_inherited_viewport_scissor[] 1316 * [[VUID-vkCmdSetViewport-commandBuffer-04821]] 1317 pname:commandBuffer must: not have 1318 slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D 1319 enabled 1320endif::VK_NV_inherited_viewport_scissor[] 1321**** 1322 1323include::{generated}/validity/protos/vkCmdSetViewport.txt[] 1324-- 1325 1326Both slink:VkPipelineViewportStateCreateInfo and flink:vkCmdSetViewport use 1327sname:VkViewport to set the viewport transformation parameters. 1328 1329[open,refpage='VkViewport',desc='Structure specifying a viewport',type='structs'] 1330-- 1331The sname:VkViewport structure is defined as: 1332 1333include::{generated}/api/structs/VkViewport.txt[] 1334 1335 * pname:x and pname:y are the viewport's upper left corner [eq]#(x,y)#. 1336 * pname:width and pname:height are the viewport's width and height, 1337 respectively. 1338 * pname:minDepth and pname:maxDepth are the depth range for the viewport. 1339 1340[NOTE] 1341.Note 1342==== 1343Despite their names, pname:minDepth can: be less than, equal to, or greater 1344than pname:maxDepth. 1345==== 1346 1347The framebuffer depth coordinate [eq]#pname:z~f~# may: be represented using 1348either a fixed-point or floating-point representation. 1349However, a floating-point representation must: be used if the depth/stencil 1350attachment has a floating-point depth component. 1351If an [eq]#m#-bit fixed-point representation is used, we assume that it 1352represents each value latexmath:[\frac{k}{2^m - 1}], where [eq]#k {elem} { 13530, 1, ..., 2^m^-1 }#, as [eq]#k# (e.g. 1.0 is represented in binary as a 1354string of all ones). 1355 1356The viewport parameters shown in the above equations are found from these 1357values as 1358 1359 {empty}:: [eq]#o~x~ = pname:x {plus} pname:width / 2# 1360 {empty}:: [eq]#o~y~ = pname:y {plus} pname:height / 2# 1361 {empty}:: [eq]#o~z~ = pname:minDepth# 1362 {empty}:: [eq]#p~x~ = pname:width# 1363 {empty}:: [eq]#p~y~ = pname:height# 1364 {empty}:: [eq]#p~z~ = pname:maxDepth - pname:minDepth#. 1365 1366ifdef::VK_QCOM_render_pass_transform[] 1367If a render pass transform is enabled, the values [eq]#(p~x~,p~y~)# and 1368[eq]#(o~x~, o~y~)# defining the viewport are transformed as described in 1369<<vertexpostproc-renderpass-transform, render pass transform>> before 1370participating in the viewport transform. 1371endif::VK_QCOM_render_pass_transform[] 1372 1373ifdef::VK_VERSION_1_1,VK_KHR_maintenance1[] 1374The application can: specify a negative term for pname:height, which has the 1375effect of negating the y coordinate in clip space before performing the 1376transform. 1377When using a negative pname:height, the application should: also adjust the 1378pname:y value to point to the lower left corner of the viewport instead of 1379the upper left corner. 1380Using the negative pname:height allows the application to avoid having to 1381negate the y component of the code:Position output from the last 1382<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1383stage>>. 1384endif::VK_VERSION_1_1,VK_KHR_maintenance1[] 1385 1386The width and height of the <<limits-maxViewportDimensions, 1387implementation-dependent maximum viewport dimensions>> must: be greater than 1388or equal to the width and height of the largest image which can: be created 1389and attached to a framebuffer. 1390 1391The floating-point viewport bounds are represented with an 1392<<limits-viewportSubPixelBits,implementation-dependent precision>>. 1393 1394.Valid Usage 1395**** 1396 * [[VUID-VkViewport-width-01770]] 1397 pname:width must: be greater than `0.0` 1398 * [[VUID-VkViewport-width-01771]] 1399 pname:width must: be less than or equal to 1400 sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[0] 1401ifndef::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[] 1402 * [[VUID-VkViewport-height-01772]] 1403 pname:height must: be greater than `0.0` 1404endif::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[] 1405 * [[VUID-VkViewport-height-01773]] 1406 The absolute value of pname:height must: be less than or equal to 1407 sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[1] 1408 * [[VUID-VkViewport-x-01774]] 1409 pname:x must: be greater than or equal to pname:viewportBoundsRange[0] 1410 * [[VUID-VkViewport-x-01232]] 1411 [eq]#(pname:x {plus} pname:width)# must: be less than or equal to 1412 pname:viewportBoundsRange[1] 1413 * [[VUID-VkViewport-y-01775]] 1414 pname:y must: be greater than or equal to pname:viewportBoundsRange[0] 1415ifdef::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[] 1416 * [[VUID-VkViewport-y-01776]] 1417 pname:y must: be less than or equal to pname:viewportBoundsRange[1] 1418 * [[VUID-VkViewport-y-01777]] 1419 [eq]#(pname:y {plus} pname:height)# must: be greater than or equal to 1420 pname:viewportBoundsRange[0] 1421endif::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[] 1422 * [[VUID-VkViewport-y-01233]] 1423 [eq]#(pname:y {plus} pname:height)# must: be less than or equal to 1424 pname:viewportBoundsRange[1] 1425ifdef::VK_EXT_depth_range_unrestricted[] 1426 * [[VUID-VkViewport-minDepth-01234]] 1427 Unless `apiext:VK_EXT_depth_range_unrestricted` extension is enabled 1428 pname:minDepth must: be between `0.0` and `1.0`, inclusive 1429endif::VK_EXT_depth_range_unrestricted[] 1430ifndef::VK_EXT_depth_range_unrestricted[] 1431 * [[VUID-VkViewport-minDepth-02540]] 1432 pname:minDepth must: be between `0.0` and `1.0`, inclusive 1433endif::VK_EXT_depth_range_unrestricted[] 1434ifdef::VK_EXT_depth_range_unrestricted[] 1435 * [[VUID-VkViewport-maxDepth-01235]] 1436 Unless `apiext:VK_EXT_depth_range_unrestricted` extension is enabled 1437 pname:maxDepth must: be between `0.0` and `1.0`, inclusive 1438endif::VK_EXT_depth_range_unrestricted[] 1439ifndef::VK_EXT_depth_range_unrestricted[] 1440 * [[VUID-VkViewport-maxDepth-02541]] 1441 pname:maxDepth must: be between `0.0` and `1.0`, inclusive 1442endif::VK_EXT_depth_range_unrestricted[] 1443**** 1444 1445include::{generated}/validity/structs/VkViewport.txt[] 1446-- 1447