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 \\ 650z_m \leq z_c \leq w_c 651\end{array} 652++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 653 654where 655ifdef::VK_EXT_depth_clip_control[] 656if 657slink:VkPipelineViewportDepthClipControlCreateInfoEXT::pname:negativeOneToOne 658is ename:VK_TRUE [eq]#z~m~# is equal to [eq]#-w~c~# otherwise 659endif::VK_EXT_depth_clip_control[] 660[eq]#z~m~# is equal to zero. 661 662This view volume can: be further restricted by as many as 663sname:VkPhysicalDeviceLimits::pname:maxClipDistances client-defined 664half-spaces. 665 666The cull volume is the intersection of up to 667sname:VkPhysicalDeviceLimits::pname:maxCullDistances client-defined 668half-spaces (if no client-defined cull half-spaces are enabled, culling 669against the cull volume is skipped). 670 671A shader must: write a single cull distance for each enabled cull half-space 672to elements of the code:CullDistance array. 673If the cull distance for any enabled cull half-space is negative for all of 674the vertices of the primitive under consideration, the primitive is 675discarded. 676Otherwise the primitive is clipped against the clip volume as defined below. 677 678The clip volume is the intersection of up to 679sname:VkPhysicalDeviceLimits::pname:maxClipDistances client-defined 680half-spaces with the view volume (if no client-defined clip half-spaces are 681enabled, the clip volume is the view volume). 682 683A shader must: write a single clip distance for each enabled clip half-space 684to elements of the code:ClipDistance array. 685Clip half-space [eq]#i# is then given by the set of points satisfying the 686inequality 687 688 {empty}:: [eq]#c~i~(**P**) {geq} 0# 689 690where [eq]#c~i~(**P**)# is the clip distance [eq]#i# at point [eq]#**P**#. 691For point primitives, [eq]#c~i~(**P**)# is simply the clip distance for the 692vertex in question. 693For line and triangle primitives, per-vertex clip distances are interpolated 694using a weighted mean, with weights derived according to the algorithms 695described in sections <<primsrast-lines-basic,Basic Line Segment 696Rasterization>> and <<primsrast-polygons-basic,Basic Polygon 697Rasterization>>, using the perspective interpolation equations. 698 699The number of client-defined clip and cull half-spaces that are enabled is 700determined by the explicit size of the built-in arrays code:ClipDistance and 701code:CullDistance, respectively, declared as an output in the interface of 702the entry point of the final shader stage before clipping. 703 704ifdef::VK_EXT_depth_clip_enable[] 705If slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT is present in 706the graphics pipeline state then depth clipping is disabled if 707slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT::pname:depthClipEnable 708is ename:VK_FALSE. 709Otherwise, if slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT is 710not present, depth clipping is disabled when 711slink:VkPipelineRasterizationStateCreateInfo::pname:depthClampEnable is 712ename:VK_TRUE. 713endif::VK_EXT_depth_clip_enable[] 714ifndef::VK_EXT_depth_clip_enable[] 715Depth clamping is enabled or disabled via the pname:depthClampEnable enable 716of the slink:VkPipelineRasterizationStateCreateInfo structure. 717Depth clipping is disabled when pname:depthClampEnable is ename:VK_TRUE. 718endif::VK_EXT_depth_clip_enable[] 719When depth clipping is disabled, the plane equation 720 721 {empty}:: [eq]#z~m~ {leq} z~c~ {leq} w~c~# 722 723(see the clip volume definition above) is ignored by view volume clipping 724(effectively, there is no near or far plane clipping). 725 726If the primitive under consideration is a point or line segment, then 727clipping passes it unchanged if its vertices lie entirely within the clip 728volume. 729 730ifndef::VK_VERSION_1_1,VK_KHR_maintenance2[] 731If a point's vertex lies outside of the clip volume, the entire primitive 732may: be discarded. 733endif::VK_VERSION_1_1,VK_KHR_maintenance2[] 734 735ifdef::VK_VERSION_1_1,VK_KHR_maintenance2[] 736[open,refpage='VkPointClippingBehavior',desc='Enum specifying the point clipping behavior',type='enums'] 737-- 738Possible values of 739slink:VkPhysicalDevicePointClippingProperties::pname:pointClippingBehavior, 740specifying clipping behavior of a point primitive whose vertex lies outside 741the clip volume, are: 742 743include::{generated}/api/enums/VkPointClippingBehavior.txt[] 744 745ifdef::VK_KHR_maintenance2[] 746or the equivalent 747 748include::{generated}/api/enums/VkPointClippingBehaviorKHR.txt[] 749endif::VK_KHR_maintenance2[] 750 751 * ename:VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES specifies that the 752 primitive is discarded if the vertex lies outside any clip plane, 753 including the planes bounding the view volume. 754 * ename:VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY specifies that 755 the primitive is discarded only if the vertex lies outside any user clip 756 plane. 757-- 758endif::VK_VERSION_1_1,VK_KHR_maintenance2[] 759 760If either of a line segment's vertices lie outside of the clip volume, the 761line segment may: be clipped, with new vertex coordinates computed for each 762vertex that lies outside the clip volume. 763A clipped line segment endpoint lies on both the original line segment and 764the boundary of the clip volume. 765 766This clipping produces a value, [eq]#0 {leq} t {leq} 1#, for each clipped 767vertex. 768If the coordinates of a clipped vertex are [eq]#**P**# and the unclipped 769line segment's vertex coordinates are [eq]#**P**~1~# and [eq]#**P**~2~#, 770then [eq]#t# satisfies the following equation 771 772 {empty}:: [eq]#**P** = t **P**~1~ {plus} (1-t) **P**~2~#. 773 774[eq]#t# is used to clip vertex output attributes as described in 775<<vertexpostproc-clipping-shader-outputs,Clipping Shader Outputs>>. 776 777If the primitive is a polygon, it passes unchanged if every one of its edges 778lies entirely inside the clip volume, and is either clipped or discarded 779otherwise. 780If the edges of the polygon intersect the boundary of the clip volume, the 781intersecting edges are reconnected by new edges that lie along the boundary 782of the clip volume - in some cases requiring the introduction of new 783vertices into a polygon. 784 785If a polygon intersects an edge of the clip volume's boundary, the clipped 786polygon must: include a point on this boundary edge. 787 788Primitives rendered with user-defined half-spaces must: satisfy a 789complementarity criterion. 790Suppose a series of primitives is drawn where each vertex [eq]#i# has a 791single specified clip distance [eq]#d~i~# (or a number of similarly 792specified clip distances, if multiple half-spaces are enabled). 793Next, suppose that the same series of primitives are drawn again with each 794such clip distance replaced by [eq]#-d~i~# (and the graphics pipeline is 795otherwise the same). 796In this case, primitives must: not be missing any pixels, and pixels must: 797not be drawn twice in regions where those primitives are cut by the clip 798planes. 799 800ifdef::VK_EXT_depth_clip_control[] 801 802[open,refpage='VkPipelineViewportDepthClipControlCreateInfoEXT',desc='Structure specifying parameters of a newly created pipeline depth clip control state',type='structs'] 803-- 804 805The sname:VkPipelineViewportDepthClipControlCreateInfoEXT structure is 806defined as: 807 808include::{generated}/api/structs/VkPipelineViewportDepthClipControlCreateInfoEXT.txt[] 809 810 * pname:sType is the type of this structure. 811 * pname:pNext is `NULL` or a pointer to a structure extending this 812 structure. 813 * pname:negativeOneToOne sets the [eq]#z~m~# in the _view volume_ to 814 [eq]#-w~c~# 815 816.Valid Usage 817**** 818 * [[VUID-VkPipelineViewportDepthClipControlCreateInfoEXT-negativeOneToOne-06470]] 819 If <<features-depthClipControl,depthClipControl>> is not enabled, 820 pname:negativeOneToOne must: be ename:VK_FALSE 821**** 822 823include::{generated}/validity/structs/VkPipelineViewportDepthClipControlCreateInfoEXT.txt[] 824-- 825 826endif::VK_EXT_depth_clip_control[] 827 828[[vertexpostproc-clipping-shader-outputs]] 829== Clipping Shader Outputs 830 831Next, vertex output attributes are clipped. 832The output values associated with a vertex that lies within the clip volume 833are unaffected by clipping. 834If a primitive is clipped, however, the output values assigned to vertices 835produced by clipping are clipped. 836 837Let the output values assigned to the two vertices [eq]#**P**~1~# and 838[eq]#**P**~2~# of an unclipped edge be [eq]#**c**~1~# and [eq]#**c**~2~#. 839The value of [eq]#t# (see <<vertexpostproc-clipping,Primitive Clipping>>) 840for a clipped point [eq]#**P**# is used to obtain the output value 841associated with [eq]#**P**# as 842 843 {empty}:: [eq]#**c** = t **c**~1~ {plus} (1-t) **c**~2~#. 844 845(Multiplying an output value by a scalar means multiplying each of _x_, _y_, 846_z_, and _w_ by the scalar.) 847 848Since this computation is performed in clip space before division by 849[eq]#w~c~#, clipped output values are perspective-correct. 850 851Polygon clipping creates a clipped vertex along an edge of the clip volume's 852boundary. 853This situation is handled by noting that polygon clipping proceeds by 854clipping against one half-space at a time. 855Output value clipping is done in the same way, so that clipped points always 856occur at the intersection of polygon edges (possibly already clipped) with 857the clip volume's boundary. 858 859For vertex output attributes whose matching fragment input attributes are 860decorated with code:NoPerspective, the value of [eq]#t# used to obtain the 861output value associated with [eq]#**P**# will be adjusted to produce results 862that vary linearly in framebuffer space. 863 864Output attributes of integer or unsigned integer type must: always be flat 865shaded. 866Flat shaded attributes are constant over the primitive being rasterized (see 867<<primsrast-lines-basic,Basic Line Segment Rasterization>> and 868<<primsrast-polygons-basic,Basic Polygon Rasterization>>), and no 869interpolation is performed. 870The output value [eq]#**c**# is taken from either [eq]#**c**~1~# or 871[eq]#**c**~2~#, since flat shading has already occurred and the two values 872are identical. 873 874ifdef::VK_NV_clip_space_w_scaling[] 875include::{chapters}/VK_NV_clip_space_w_scaling/vertexpostproc.txt[] 876endif::VK_NV_clip_space_w_scaling[] 877 878 879[[vertexpostproc-coord-transform]] 880== Coordinate Transformations 881 882_Clip coordinates_ for a vertex result from shader execution, which yields a 883vertex coordinate code:Position. 884 885Perspective division on clip coordinates yields _normalized device 886coordinates_, followed by a _viewport_ transformation (see 887<<vertexpostproc-viewport,Controlling the Viewport>>) to convert these 888coordinates into _framebuffer coordinates_. 889 890If a vertex in clip coordinates has a position given by 891 892[latexmath] 893++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 894\left(\begin{array}{c} 895x_c \\ 896y_c \\ 897z_c \\ 898w_c 899\end{array}\right) 900++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 901 902then the vertex's normalized device coordinates are 903[latexmath] 904++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 905\left( 906 \begin{array}{c} 907 x_d \\ 908 y_d \\ 909 z_d 910 \end{array} 911\right) = 912\left( 913 \begin{array}{c} 914 \frac{x_c}{w_c} \\ 915 \frac{y_c}{w_c} \\ 916 \frac{z_c}{w_c} 917 \end{array} 918\right) 919++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 920 921 922ifdef::VK_QCOM_render_pass_transform[] 923[[vertexpostproc-renderpass-transform]] 924== Render Pass Transform 925 926A _render pass transform_ can: be enabled for render pass instances. 927The clip coordinates [eq]#(x~c~, y~c~)# that result from vertex shader 928execution are transformed by a rotation of 0, 90, 180, or 270 degrees in the 929XY plane, centered at the origin. 930 931When _Render pass transform_ is enabled, the transform applies to all 932primitives for all subpasses of the render pass. 933The transformed vertex in clip coordinates has a position given by 934 935[latexmath] 936++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 937\left( 938 \begin{array}{c} 939 x_{c_{trans}} \\ 940 y_{c_{trans}} \\ 941 z_{c_{trans}} 942 \end{array} 943\right) = 944\left( 945 \begin{array}{c} 946 x_{c} \cos \theta - y_{c} \sin \theta \\ 947 x_{c} \sin \theta + y_{c} \cos \theta \\ 948 z_c 949 \end{array} 950\right) 951++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 952 953where 954 955 * _[eq]#{theta}#_ is 0 degrees for 956 ename:VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR 957 * _[eq]#{theta}#_ is 90 degrees for 958 ename:VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR 959 * _[eq]#{theta}#_ is 180 degrees for 960 ename:VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR 961 * _[eq]#{theta}#_ is 270 degrees for 962 ename:VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR 963 964 965The transformed vertex's normalized device coordinates are 966[latexmath] 967++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 968\left( 969 \begin{array}{c} 970 x_d \\ 971 y_d \\ 972 z_d 973 \end{array} 974\right) = 975\left( 976 \begin{array}{c} 977 \frac{x_{c_{trans}}}{w_c} \\ 978 \frac{y_{c_{trans}}}{w_c} \\ 979 \frac{z_{c_{trans}}}{w_c} 980 \end{array} 981\right) 982++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 983 984 985When render pass transform is enabled for a render pass instance, the 986following additional features are enabled: 987 988 * Each slink:VkViewport specified by either 989 slink:VkPipelineViewportStateCreateInfo::pname:pViewports or 990 flink:vkCmdSetViewport will have its width/height [eq]#(p~x~, p~y~)# and 991 its center [eq]#(o~x~, o~y~)# similarly transformed by the 992 implementation. 993 * Each scissor specified by 994 slink:VkPipelineViewportStateCreateInfo::pname:pScissors or 995 flink:vkCmdSetScissor will have its [eq]#(offset~x~, offset~y~)# and 996 [eq]#(extent~x~, extent~y~)# similarly transformed by the 997 implementation. 998 * The pname:renderArea specified in 999 slink:VkCommandBufferInheritanceRenderPassTransformInfoQCOM and 1000 slink:VkRenderPassBeginInfo will be similarly transformed by the 1001 implementation. 1002 * The [eq]#(x, y)# components of shader variables with built-in 1003 decorations code:FragCoord, code:SamplePosition, or code:PointCoord will 1004 be similarly transformed by the implementation. 1005 * The [eq]#(x,y)# components of the code:offset operand of the 1006 code:InterpolateAtOffset extended instruction will be similarly 1007 transformed by the implementation. 1008 * The values returned by SPIR-V <<shaders-derivative-operations, 1009 derivative instructions>> code:OpDPdx, code:OpDPdy, code:OpDPdxCourse, 1010 code:OpDPdyCourse, code:OpDPdxFine, code:OpDPdyFine will be similarly 1011 transformed by the implementation. 1012 1013 1014The net result of the above, is that applications can: act as if rendering 1015to a framebuffer oriented with the 1016slink:VkSurfaceCapabilitiesKHR::pname:currentTransform. 1017In other words, applications can: act as if the presentation engine will be 1018performing the transformation of the swapchain image after rendering and 1019prior to presentation to the user. 1020In fact, the transformation of the various items cited above are being 1021handled by the implementation as the rendering takes place. 1022 1023endif::VK_QCOM_render_pass_transform[] 1024 1025 1026[[vertexpostproc-viewport]] 1027== Controlling the Viewport 1028 1029The viewport transformation is determined by the selected viewport's width 1030and height in pixels, [eq]#p~x~# and [eq]#p~y~#, respectively, and its 1031center [eq]#(o~x~, o~y~)# (also in pixels), as well as its depth range min 1032and max determining a depth range scale value [eq]#p~z~# and a depth range 1033bias value [eq]#o~z~# (defined below). 1034The vertex's framebuffer coordinates [eq]#(x~f~, y~f~, z~f~)# are given by 1035 1036 {empty}:: [eq]#x~f~ = (p~x~ / 2) x~d~ {plus} o~x~# 1037 {empty}:: [eq]#y~f~ = (p~y~ / 2) y~d~ {plus} o~y~# 1038 {empty}:: [eq]#z~f~ = p~z~ {times} z~d~ {plus} o~z~# 1039 1040Multiple viewports are available, numbered zero up to 1041sname:VkPhysicalDeviceLimits::pname:maxViewports minus one. 1042The number of viewports used by a pipeline is controlled by the 1043pname:viewportCount member of the sname:VkPipelineViewportStateCreateInfo 1044structure used in pipeline creation. 1045 1046[eq]#x~f~# and [eq]#y~f~# have limited precision, where the number of 1047fractional bits retained is specified by 1048sname:VkPhysicalDeviceLimits::pname:subPixelPrecisionBits. 1049ifdef::VK_EXT_line_rasterization[] 1050When rasterizing <<primsrast-lines,line segments>>, the number of fractional 1051bits is specified by 1052sname:VkPhysicalDeviceLineRasterizationPropertiesEXT::pname:lineSubPixelPrecisionBits. 1053endif::VK_EXT_line_rasterization[] 1054 1055[open,refpage='VkPipelineViewportStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline viewport state',type='structs'] 1056-- 1057The sname:VkPipelineViewportStateCreateInfo structure is defined as: 1058 1059include::{generated}/api/structs/VkPipelineViewportStateCreateInfo.txt[] 1060 1061 * pname:sType is the type of this structure. 1062 * pname:pNext is `NULL` or a pointer to a structure extending this 1063 structure. 1064 * pname:flags is reserved for future use. 1065 * pname:viewportCount is the number of viewports used by the pipeline. 1066 * pname:pViewports is a pointer to an array of slink:VkViewport 1067 structures, defining the viewport transforms. 1068 If the viewport state is dynamic, this member is ignored. 1069 * pname:scissorCount is the number of <<fragops-scissor,scissors>> and 1070 must: match the number of viewports. 1071 * pname:pScissors is a pointer to an array of slink:VkRect2D structures 1072 defining the rectangular bounds of the scissor for the corresponding 1073 viewport. 1074 If the scissor state is dynamic, this member is ignored. 1075 1076.Valid Usage 1077**** 1078 * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216]] 1079 If the <<features-multiViewport,multiple viewports>> feature is not 1080 enabled, pname:viewportCount must: not be greater than `1` 1081 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217]] 1082 If the <<features-multiViewport,multiple viewports>> feature is not 1083 enabled, pname:scissorCount must: not be greater than `1` 1084 * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218]] 1085 pname:viewportCount must: be less than or equal to 1086 sname:VkPhysicalDeviceLimits::pname:maxViewports 1087 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219]] 1088 pname:scissorCount must: be less than or equal to 1089 sname:VkPhysicalDeviceLimits::pname:maxViewports 1090ifndef::VK_EXT_extended_dynamic_state[] 1091 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220]] 1092 pname:scissorCount and pname:viewportCount must: be identical 1093endif::VK_EXT_extended_dynamic_state[] 1094 * [[VUID-VkPipelineViewportStateCreateInfo-x-02821]] 1095 The pname:x and pname:y members of pname:offset member of any element of 1096 pname:pScissors must: be greater than or equal to `0` 1097 * [[VUID-VkPipelineViewportStateCreateInfo-offset-02822]] 1098 Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# must: not 1099 cause a signed integer addition overflow for any element of 1100 pname:pScissors 1101 * [[VUID-VkPipelineViewportStateCreateInfo-offset-02823]] 1102 Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# must: 1103 not cause a signed integer addition overflow for any element of 1104 pname:pScissors 1105ifndef::VK_EXT_extended_dynamic_state[] 1106 * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength]] 1107 pname:viewportCount must: be greater than `0` 1108 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength]] 1109 pname:scissorCount must: be greater than `0` 1110endif::VK_EXT_extended_dynamic_state[] 1111ifdef::VK_EXT_extended_dynamic_state[] 1112 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-04134]] 1113 If the graphics pipeline is being created without 1114 ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT and 1115 ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT set then 1116 pname:scissorCount and pname:viewportCount must: be identical 1117 * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135]] 1118 If the graphics pipeline is being created with 1119 ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT set then 1120 pname:viewportCount must: be `0`, otherwise it must: be greater than `0` 1121 * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136]] 1122 If the graphics pipeline is being created with 1123 ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT set then 1124 pname:scissorCount must: be `0`, otherwise it must: be greater than `0` 1125endif::VK_EXT_extended_dynamic_state[] 1126ifdef::VK_NV_clip_space_w_scaling[] 1127 * [[VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726]] 1128 If the pname:viewportWScalingEnable member of a 1129 slink:VkPipelineViewportWScalingStateCreateInfoNV structure included in 1130 the pname:pNext chain is ename:VK_TRUE, the pname:viewportCount member 1131 of the slink:VkPipelineViewportWScalingStateCreateInfoNV structure must: 1132 be greater than or equal to 1133 slink:VkPipelineViewportStateCreateInfo::pname:viewportCount 1134endif::VK_NV_clip_space_w_scaling[] 1135**** 1136 1137include::{generated}/validity/structs/VkPipelineViewportStateCreateInfo.txt[] 1138-- 1139 1140ifdef::VK_EXT_extended_dynamic_state[] 1141[open,refpage='vkCmdSetViewportWithCountEXT',desc='Set the viewport count and viewports dynamically for a command buffer',type='protos'] 1142-- 1143To <<pipelines-dynamic-state, dynamically set>> the viewport count and 1144viewports, call: 1145 1146include::{generated}/api/protos/vkCmdSetViewportWithCountEXT.txt[] 1147 1148 * pname:commandBuffer is the command buffer into which the command will be 1149 recorded. 1150 * pname:viewportCount specifies the viewport count. 1151 * pname:pViewports specifies the viewports to use for drawing. 1152 1153This command sets the viewport count and viewports state for subsequent 1154drawing commands when the graphics pipeline is created with 1155ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT set in 1156slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. 1157Otherwise, this state is specified by the corresponding 1158slink:VkPipelineViewportStateCreateInfo::pname:viewportCount and 1159pname:pViewports values used to create the currently active pipeline. 1160 1161.Valid Usage 1162**** 1163 * [[VUID-vkCmdSetViewportWithCountEXT-None-03393]] 1164 The <<features-extendedDynamicState, extendedDynamicState>> feature 1165 must: be enabled 1166 * [[VUID-vkCmdSetViewportWithCountEXT-viewportCount-03394]] 1167 pname:viewportCount must: be between `1` and 1168 sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive 1169 * [[VUID-vkCmdSetViewportWithCountEXT-viewportCount-03395]] 1170 If the <<features-multiViewport,multiple viewports>> feature is not 1171 enabled, pname:viewportCount must: be `1` 1172ifdef::VK_NV_inherited_viewport_scissor[] 1173 * [[VUID-vkCmdSetViewportWithCountEXT-commandBuffer-04819]] 1174 pname:commandBuffer must: not have 1175 slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D 1176 enabled 1177endif::VK_NV_inherited_viewport_scissor[] 1178**** 1179 1180include::{generated}/validity/protos/vkCmdSetViewportWithCountEXT.txt[] 1181-- 1182 1183[open,refpage='vkCmdSetScissorWithCountEXT',desc='Set the scissor count and scissor rectangular bounds dynamically for a command buffer',type='protos'] 1184-- 1185To <<pipelines-dynamic-state, dynamically set>> the scissor count and 1186scissor rectangular bounds, call: 1187 1188include::{generated}/api/protos/vkCmdSetScissorWithCountEXT.txt[] 1189 1190 * pname:commandBuffer is the command buffer into which the command will be 1191 recorded. 1192 * pname:scissorCount specifies the scissor count. 1193 * pname:pScissors specifies the scissors to use for drawing. 1194 1195This command sets the scissor count and scissor rectangular bounds state for 1196subsequence drawing commands when the graphics pipeline is created with 1197ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT set in 1198slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. 1199Otherwise, this state is specified by the corresponding 1200slink:VkPipelineViewportStateCreateInfo::pname:scissorCount and 1201pname:pScissors values used to create the currently active pipeline. 1202 1203.Valid Usage 1204**** 1205 * [[VUID-vkCmdSetScissorWithCountEXT-None-03396]] 1206 The <<features-extendedDynamicState, extendedDynamicState>> feature 1207 must: be enabled 1208 * [[VUID-vkCmdSetScissorWithCountEXT-scissorCount-03397]] 1209 pname:scissorCount must: be between `1` and 1210 sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive 1211 * [[VUID-vkCmdSetScissorWithCountEXT-scissorCount-03398]] 1212 If the <<features-multiViewport,multiple viewports>> feature is not 1213 enabled, pname:scissorCount must: be `1` 1214 * [[VUID-vkCmdSetScissorWithCountEXT-x-03399]] 1215 The pname:x and pname:y members of pname:offset member of any element of 1216 pname:pScissors must: be greater than or equal to `0` 1217 * [[VUID-vkCmdSetScissorWithCountEXT-offset-03400]] 1218 Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# must: not 1219 cause a signed integer addition overflow for any element of 1220 pname:pScissors 1221 * [[VUID-vkCmdSetScissorWithCountEXT-offset-03401]] 1222 Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# must: 1223 not cause a signed integer addition overflow for any element of 1224 pname:pScissors 1225ifdef::VK_NV_inherited_viewport_scissor[] 1226 * [[VUID-vkCmdSetScissorWithCountEXT-commandBuffer-04820]] 1227 pname:commandBuffer must: not have 1228 slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D 1229 enabled 1230endif::VK_NV_inherited_viewport_scissor[] 1231**** 1232 1233include::{generated}/validity/protos/vkCmdSetScissorWithCountEXT.txt[] 1234-- 1235endif::VK_EXT_extended_dynamic_state[] 1236 1237[open,refpage='VkPipelineViewportStateCreateFlags',desc='Reserved for future use',type='flags'] 1238-- 1239include::{generated}/api/flags/VkPipelineViewportStateCreateFlags.txt[] 1240 1241tname:VkPipelineViewportStateCreateFlags is a bitmask type for setting a 1242mask, but is currently reserved for future use. 1243-- 1244 1245ifndef::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] 1246If a geometry shader is active and has an output variable decorated with 1247code:ViewportIndex, the viewport transformation uses the viewport 1248corresponding to the value assigned to code:ViewportIndex taken from an 1249implementation-dependent vertex of each primitive. 1250If code:ViewportIndex is outside the range zero to pname:viewportCount minus 1251one for a primitive, or if the geometry shader did not assign a value to 1252code:ViewportIndex for all vertices of a primitive due to flow control, the 1253values resulting from the viewport transformation of the vertices of such 1254primitives are undefined:. 1255If no geometry shader is active, or if the geometry shader does not have an 1256output decorated with code:ViewportIndex, the viewport numbered zero is used 1257by the viewport transformation. 1258endif::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] 1259 1260ifdef::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] 1261ifdef::VK_NV_viewport_array2[] 1262A _<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1263stage>>_ can: direct each primitive to zero or more viewports. 1264The destination viewports for a primitive are selected by the last active 1265<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1266stage>> that has an output variable decorated with code:ViewportIndex 1267(selecting a single viewport) or code:ViewportMaskNV (selecting multiple 1268viewports). 1269The viewport transform uses the viewport corresponding to either the value 1270assigned to code:ViewportIndex or one of the bits set in 1271code:ViewportMaskNV, and taken from an implementation-dependent vertex of 1272each primitive. 1273If code:ViewportIndex or any of the bits in code:ViewportMaskNV are outside 1274the range zero to pname:viewportCount minus one for a primitive, or if the 1275last active <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization 1276shader stage>> did not assign a value to either code:ViewportIndex or 1277code:ViewportMaskNV for all vertices of a primitive due to flow control, the 1278values resulting from the viewport transformation of the vertices of such 1279primitives are undefined:. 1280If the last <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization 1281shader stage>> does not have an output decorated with code:ViewportIndex or 1282code:ViewportMaskNV, the viewport numbered zero is used by the viewport 1283transformation. 1284endif::VK_NV_viewport_array2[] 1285ifndef::VK_NV_viewport_array2[] 1286A _<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1287stage>>_ can: direct each primitive to one of several viewports. 1288The destination viewport for a primitive is selected by the last active 1289<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1290stage>> that has an output variable decorated with code:ViewportIndex. 1291The viewport transform uses the viewport corresponding to the value assigned 1292to code:ViewportIndex, and taken from an implementation-dependent vertex of 1293each primitive. 1294If code:ViewportIndex is outside the range zero to pname:viewportCount minus 1295one for a primitive, or if the last active 1296<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1297stage>> did not assign a value to code:ViewportIndex for all vertices of a 1298primitive due to flow control, the values resulting from the viewport 1299transformation of the vertices of such primitives are undefined:. 1300If the last <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization 1301shader stage>> does not have an output decorated with code:ViewportIndex, 1302the viewport numbered zero is used by the viewport transformation. 1303endif::VK_NV_viewport_array2[] 1304endif::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] 1305 1306A single vertex can: be used in more than one individual primitive, in 1307primitives such as ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP. 1308In this case, the viewport transformation is applied separately for each 1309primitive. 1310 1311[open,refpage='vkCmdSetViewport',desc='Set the viewport dynamically for a command buffer',type='protos'] 1312-- 1313To <<pipelines-dynamic-state, dynamically set>> the viewport transformation 1314parameters, call: 1315 1316include::{generated}/api/protos/vkCmdSetViewport.txt[] 1317 1318 * pname:commandBuffer is the command buffer into which the command will be 1319 recorded. 1320 * pname:firstViewport is the index of the first viewport whose parameters 1321 are updated by the command. 1322 * pname:viewportCount is the number of viewports whose parameters are 1323 updated by the command. 1324 * pname:pViewports is a pointer to an array of slink:VkViewport structures 1325 specifying viewport parameters. 1326 1327This command sets the viewport transformation parameters state for 1328subsequent drawing commands when the graphics pipeline is created with 1329ename:VK_DYNAMIC_STATE_VIEWPORT set in 1330slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. 1331Otherwise, this state is specified by the 1332sname:VkPipelineViewportStateCreateInfo::pname:pViewports values used to 1333create the currently active pipeline. 1334 1335The viewport parameters taken from element [eq]#i# of pname:pViewports 1336replace the current state for the viewport index [eq]#pname:firstViewport 1337{plus} i#, for [eq]#i# in [eq]#[0, pname:viewportCount)#. 1338 1339.Valid Usage 1340**** 1341 * [[VUID-vkCmdSetViewport-firstViewport-01223]] 1342 The sum of pname:firstViewport and pname:viewportCount must: be between 1343 `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive 1344 * [[VUID-vkCmdSetViewport-firstViewport-01224]] 1345 If the <<features-multiViewport,multiple viewports>> feature is not 1346 enabled, pname:firstViewport must: be `0` 1347 * [[VUID-vkCmdSetViewport-viewportCount-01225]] 1348 If the <<features-multiViewport,multiple viewports>> feature is not 1349 enabled, pname:viewportCount must: be `1` 1350ifdef::VK_NV_inherited_viewport_scissor[] 1351 * [[VUID-vkCmdSetViewport-commandBuffer-04821]] 1352 pname:commandBuffer must: not have 1353 slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D 1354 enabled 1355endif::VK_NV_inherited_viewport_scissor[] 1356**** 1357 1358include::{generated}/validity/protos/vkCmdSetViewport.txt[] 1359-- 1360 1361Both slink:VkPipelineViewportStateCreateInfo and flink:vkCmdSetViewport use 1362sname:VkViewport to set the viewport transformation parameters. 1363 1364[open,refpage='VkViewport',desc='Structure specifying a viewport',type='structs'] 1365-- 1366The sname:VkViewport structure is defined as: 1367 1368include::{generated}/api/structs/VkViewport.txt[] 1369 1370 * pname:x and pname:y are the viewport's upper left corner [eq]#(x,y)#. 1371 * pname:width and pname:height are the viewport's width and height, 1372 respectively. 1373 * pname:minDepth and pname:maxDepth are the depth range for the viewport. 1374 1375[NOTE] 1376.Note 1377==== 1378Despite their names, pname:minDepth can: be less than, equal to, or greater 1379than pname:maxDepth. 1380==== 1381 1382The framebuffer depth coordinate [eq]#pname:z~f~# may: be represented using 1383either a fixed-point or floating-point representation. 1384However, a floating-point representation must: be used if the depth/stencil 1385attachment has a floating-point depth component. 1386If an [eq]#m#-bit fixed-point representation is used, we assume that it 1387represents each value latexmath:[\frac{k}{2^m - 1}], where [eq]#k {elem} { 13880, 1, ..., 2^m^-1 }#, as [eq]#k# (e.g. 1.0 is represented in binary as a 1389string of all ones). 1390 1391The viewport parameters shown in the above equations are found from these 1392values as 1393 1394 {empty}:: [eq]#o~x~ = pname:x {plus} pname:width / 2# 1395 {empty}:: [eq]#o~y~ = pname:y {plus} pname:height / 2# 1396 {empty}:: [eq]#o~z~ = pname:minDepth# 1397 {empty}:: [eq]#p~x~ = pname:width# 1398 {empty}:: [eq]#p~y~ = pname:height# 1399 {empty}:: [eq]#p~z~ = pname:maxDepth - pname:minDepth#. 1400 1401ifdef::VK_QCOM_render_pass_transform[] 1402If a render pass transform is enabled, the values [eq]#(p~x~,p~y~)# and 1403[eq]#(o~x~, o~y~)# defining the viewport are transformed as described in 1404<<vertexpostproc-renderpass-transform, render pass transform>> before 1405participating in the viewport transform. 1406endif::VK_QCOM_render_pass_transform[] 1407 1408ifdef::VK_VERSION_1_1,VK_KHR_maintenance1[] 1409The application can: specify a negative term for pname:height, which has the 1410effect of negating the y coordinate in clip space before performing the 1411transform. 1412When using a negative pname:height, the application should: also adjust the 1413pname:y value to point to the lower left corner of the viewport instead of 1414the upper left corner. 1415Using the negative pname:height allows the application to avoid having to 1416negate the y component of the code:Position output from the last 1417<<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader 1418stage>>. 1419endif::VK_VERSION_1_1,VK_KHR_maintenance1[] 1420 1421The width and height of the <<limits-maxViewportDimensions, 1422implementation-dependent maximum viewport dimensions>> must: be greater than 1423or equal to the width and height of the largest image which can: be created 1424and attached to a framebuffer. 1425 1426The floating-point viewport bounds are represented with an 1427<<limits-viewportSubPixelBits,implementation-dependent precision>>. 1428 1429.Valid Usage 1430**** 1431 * [[VUID-VkViewport-width-01770]] 1432 pname:width must: be greater than `0.0` 1433 * [[VUID-VkViewport-width-01771]] 1434 pname:width must: be less than or equal to 1435 sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[0] 1436ifndef::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[] 1437 * [[VUID-VkViewport-height-01772]] 1438 pname:height must: be greater than `0.0` 1439endif::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[] 1440 * [[VUID-VkViewport-height-01773]] 1441 The absolute value of pname:height must: be less than or equal to 1442 sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[1] 1443 * [[VUID-VkViewport-x-01774]] 1444 pname:x must: be greater than or equal to pname:viewportBoundsRange[0] 1445 * [[VUID-VkViewport-x-01232]] 1446 [eq]#(pname:x {plus} pname:width)# must: be less than or equal to 1447 pname:viewportBoundsRange[1] 1448 * [[VUID-VkViewport-y-01775]] 1449 pname:y must: be greater than or equal to pname:viewportBoundsRange[0] 1450ifdef::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[] 1451 * [[VUID-VkViewport-y-01776]] 1452 pname:y must: be less than or equal to pname:viewportBoundsRange[1] 1453 * [[VUID-VkViewport-y-01777]] 1454 [eq]#(pname:y {plus} pname:height)# must: be greater than or equal to 1455 pname:viewportBoundsRange[0] 1456endif::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[] 1457 * [[VUID-VkViewport-y-01233]] 1458 [eq]#(pname:y {plus} pname:height)# must: be less than or equal to 1459 pname:viewportBoundsRange[1] 1460ifdef::VK_EXT_depth_range_unrestricted[] 1461 * [[VUID-VkViewport-minDepth-01234]] 1462 Unless `apiext:VK_EXT_depth_range_unrestricted` extension is enabled 1463 pname:minDepth must: be between `0.0` and `1.0`, inclusive 1464endif::VK_EXT_depth_range_unrestricted[] 1465ifndef::VK_EXT_depth_range_unrestricted[] 1466 * [[VUID-VkViewport-minDepth-02540]] 1467 pname:minDepth must: be between `0.0` and `1.0`, inclusive 1468endif::VK_EXT_depth_range_unrestricted[] 1469ifdef::VK_EXT_depth_range_unrestricted[] 1470 * [[VUID-VkViewport-maxDepth-01235]] 1471 Unless `apiext:VK_EXT_depth_range_unrestricted` extension is enabled 1472 pname:maxDepth must: be between `0.0` and `1.0`, inclusive 1473endif::VK_EXT_depth_range_unrestricted[] 1474ifndef::VK_EXT_depth_range_unrestricted[] 1475 * [[VUID-VkViewport-maxDepth-02541]] 1476 pname:maxDepth must: be between `0.0` and `1.0`, inclusive 1477endif::VK_EXT_depth_range_unrestricted[] 1478**** 1479 1480include::{generated}/validity/structs/VkViewport.txt[] 1481-- 1482