| // Copyright 2015-2023 The Khronos Group Inc. |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| [[vertexpostproc]] |
| = Fixed-Function Vertex Post-Processing |
| |
| After <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization |
| shader stages>>, the following fixed-function operations are applied to |
| vertices of the resulting primitives: |
| |
| ifdef::VK_EXT_transform_feedback[] |
| * Transform feedback (see <<vertexpostproc-transform-feedback,Transform |
| Feedback>>) |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_NV_viewport_swizzle[] |
| * Viewport swizzle (see <<vertexpostproc-viewport-swizzle,Viewport |
| Swizzle>>) |
| endif::VK_NV_viewport_swizzle[] |
| * Flat shading (see <<vertexpostproc-flatshading>>). |
| * Primitive clipping, including client-defined half-spaces (see |
| <<vertexpostproc-clipping,Primitive Clipping>>). |
| * Shader output attribute clipping (see |
| <<vertexpostproc-clipping-shader-outputs,Clipping Shader Outputs>>). |
| ifdef::VK_NV_clip_space_w_scaling[] |
| * Clip space W scaling (see <<vertexpostproc-viewportwscaling,Controlling |
| Viewport W Scaling>>). |
| endif::VK_NV_clip_space_w_scaling[] |
| * Perspective division on clip coordinates (see |
| <<vertexpostproc-coord-transform,Coordinate Transformations>>). |
| * Viewport mapping, including depth range scaling (see |
| <<vertexpostproc-viewport,Controlling the Viewport>>). |
| * Front face determination for polygon primitives (see |
| <<primsrast-polygons-basic,Basic Polygon Rasterization>>). |
| |
| ifdef::editing-notes[] |
| [NOTE] |
| .editing-note |
| ==== |
| TODO:Odd that this one link to a different chapter is in this list. |
| ==== |
| endif::editing-notes[] |
| |
| Next, rasterization is performed on primitives as described in chapter |
| <<primsrast,Rasterization>>. |
| |
| |
| ifdef::VK_EXT_transform_feedback[] |
| [[vertexpostproc-transform-feedback]] |
| == Transform Feedback |
| |
| Before any other fixed-function vertex post-processing, vertex outputs from |
| the last shader in the |
| <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>> can: be written out to one or more transform feedback buffers bound |
| to the command buffer. |
| To capture vertex outputs the last |
| <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>> shader must: be declared with the code:Xfb execution mode. |
| Outputs decorated with code:XfbBuffer will be written out to the |
| corresponding transform feedback buffers bound to the command buffer when |
| transform feedback is active. |
| Transform feedback buffers are bound to the command buffer by using |
| flink:vkCmdBindTransformFeedbackBuffersEXT. |
| Transform feedback is made active by calling |
| flink:vkCmdBeginTransformFeedbackEXT and made inactive by calling |
| flink:vkCmdEndTransformFeedbackEXT. |
| After vertex data is written it is possible to use |
| flink:vkCmdDrawIndirectByteCountEXT to start a new draw where the |
| pname:vertexCount is derived from the number of bytes written by a previous |
| transform feedback. |
| |
| When an individual point, line, or triangle primitive reaches the transform |
| feedback stage while transform feedback is active, the values of the |
| specified output variables are assembled into primitives and appended to the |
| bound transform feedback buffers. |
| After activating transform feedback, the values of the first assembled |
| primitive are written at the starting offsets of the bound transform |
| feedback buffers, and subsequent primitives are appended to the buffer. |
| If the optional pname:pCounterBuffers and pname:pCounterBufferOffsets |
| parameters are specified, the starting points within the transform feedback |
| buffers are adjusted so data is appended to the previously written values |
| indicated by the value stored by the implementation in the counter buffer. |
| |
| For multi-vertex primitives, all values for a given vertex are written |
| before writing values for any other vertex. |
| ifdef::VK_EXT_provoking_vertex[] |
| When <<features-transformFeedbackPreservesProvokingVertex, |
| pname:transformFeedbackPreservesProvokingVertex>> is not enabled, |
| implementations |
| endif::VK_EXT_provoking_vertex[] |
| ifndef::VK_EXT_provoking_vertex[] |
| Implementations |
| endif::VK_EXT_provoking_vertex[] |
| may: write out any vertex within the primitive first, but all subsequent |
| vertices for that primitive must: be written out in a consistent winding |
| order defined as follows: |
| |
| * If neither <<geometry,geometry>> or <<tessellation,tessellation |
| shading>> is active, vertices within a primitive are appended according |
| to the winding order described by the <<drawing-primitive-topologies, |
| primitive topology>> defined by the |
| slink:VkPipelineInputAssemblyStateCreateInfo:pname:topology used to |
| execute the <<drawing,drawing command>>. |
| * If <<geometry,geometry shading>> is active, vertices within a primitive |
| are appended according to the winding order described by the |
| <<drawing-primitive-topologies, primitive topology>> defined by the |
| <<drawing-point-lists, code:OutputPoints>>, <<drawing-line-strips, |
| code:OutputLineStrips>>, or <<drawing-triangle-strips, |
| code:OutputTriangleStrips>> execution mode. |
| * If <<tessellation,tessellation shading>> is active but |
| <<geometry,geometry shading>> is not, vertices within a primitive are |
| appended according to the winding order defined by |
| <<tessellation-triangle-tessellation, triangle tessellation>>, |
| <<tessellation-quad-tessellation, quad tessellation>>, and |
| <<tessellation-isoline-tessellation, isoline tessellation>>. |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When <<features-transformFeedbackPreservesProvokingVertex, |
| pname:transformFeedbackPreservesProvokingVertex>> is enabled, then in |
| addition to writing vertices with a consistent winding order, the vertex |
| order must: preserve the <<vertexpostproc-flatshading, provoking vertex>> of |
| each primitive: |
| |
| * When the |
| <<VkPipelineRasterizationProvokingVertexStateCreateInfoEXT,pipeline's |
| provoking vertex mode>> is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, the primitive's |
| provoking vertex must be the first vertex written. |
| * When the |
| <<VkPipelineRasterizationProvokingVertexStateCreateInfoEXT,pipeline's |
| provoking vertex mode>> is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the primitive's |
| provoking vertex must be the last vertex written. |
| |
| If <<limits-transformFeedbackPreservesTriangleFanProvokingVertex, |
| pname:transformFeedbackPreservesTriangleFanProvokingVertex>> is |
| ename:VK_FALSE, neither <<geometry, geometry>> nor <<tessellation, |
| tessellation>> shading is active, and the <<drawing-primitive-topologies, |
| primitive topology>> is ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, then the |
| first vertex written from each primitive is implementation-defined even when |
| <<features-transformFeedbackPreservesProvokingVertex, |
| pname:transformFeedbackPreservesProvokingVertex>> is enabled. |
| |
| endif::VK_EXT_provoking_vertex[] |
| |
| When capturing vertices, the stride associated with each transform feedback |
| buffer, as indicated by the code:XfbStride decoration, indicates the number |
| of bytes of storage reserved for each vertex in the transform feedback |
| buffer. |
| For every vertex captured, each output attribute with a code:Offset |
| decoration will be written to the storage reserved for the vertex at the |
| associated transform feedback buffer. |
| When writing output variables that are arrays or structures, individual |
| array elements or structure members are written tightly packed in order. |
| For vector types, individual components are written in order. |
| For matrix types, outputs are written as an array of column vectors. |
| |
| If any component of an output with an assigned transform feedback offset was |
| not written to by its shader, the value recorded for that component is |
| undefined:. |
| All components of an output variable must: be written at an offset aligned |
| to the size of the component. |
| The size of each component of an output variable must: be at least 32-bits. |
| When capturing a vertex, any portion of the reserved storage not associated |
| with an output variable with an assigned transform feedback offset will be |
| unmodified. |
| |
| When transform feedback is inactive, no vertices are recorded. |
| If there is a valid counter buffer handle and counter buffer offset in the |
| pname:pCounterBuffers and pname:pCounterBufferOffsets arrays, writes to the |
| corresponding transform feedback buffer will start at the byte offset |
| represented by the value stored in the counter buffer location. |
| |
| Individual lines or triangles of a strip or fan primitive will be extracted |
| and recorded separately. |
| Incomplete primitives are not recorded. |
| |
| When using a geometry shader that emits vertices to multiple vertex streams, |
| a primitive will be assembled and output for each stream when there are |
| enough vertices emitted for the output primitive type. |
| All outputs assigned to a given transform feedback buffer are required to |
| come from a single vertex stream. |
| |
| The sizes of the transform feedback buffers are defined by the |
| flink:vkCmdBindTransformFeedbackBuffersEXT pname:pSizes parameter for each |
| of the bound buffers, or the size of the bound buffer, whichever is the |
| lesser. |
| If there is less space remaining in any of the transform feedback buffers |
| than the size of all of the vertex data for that primitive based on the |
| code:XfbStride for that code:XfbBuffer then no vertex data of that primitive |
| is recorded in any transform feedback buffer, and the value for the number |
| of primitives written in the corresponding |
| ename:VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT query for all transform |
| feedback buffers is no longer incremented. |
| |
| Any outputs made to a code:XfbBuffer that is not bound to a transform |
| feedback buffer is ignored. |
| |
| [open,refpage='vkCmdBindTransformFeedbackBuffersEXT',desc='Bind transform feedback buffers to a command buffer',type='protos'] |
| -- |
| To bind transform feedback buffers to a command buffer for use in subsequent |
| drawing commands, call: |
| |
| include::{generated}/api/protos/vkCmdBindTransformFeedbackBuffersEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:firstBinding is the index of the first transform feedback binding |
| whose state is updated by the command. |
| * pname:bindingCount is the number of transform feedback bindings whose |
| state is updated by the command. |
| * pname:pBuffers is a pointer to an array of buffer handles. |
| * pname:pOffsets is a pointer to an array of buffer offsets. |
| * pname:pSizes is `NULL` or a pointer to an array of basetype:VkDeviceSize |
| buffer sizes, specifying the maximum number of bytes to capture to the |
| corresponding transform feedback buffer. |
| If pname:pSizes is `NULL`, or the value of the pname:pSizes array |
| element is ename:VK_WHOLE_SIZE, then the maximum number of bytes |
| captured will be the size of the corresponding buffer minus the buffer |
| offset. |
| |
| The values taken from elements [eq]#i# of pname:pBuffers, pname:pOffsets and |
| pname:pSizes replace the current state for the transform feedback binding |
| [eq]#pname:firstBinding {plus} i#, for [eq]#i# in [eq]#[0, |
| pname:bindingCount)#. |
| The transform feedback binding is updated to start at the offset indicated |
| by pname:pOffsets[i] from the start of the buffer pname:pBuffers[i]. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-transformFeedback-02355]] |
| sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:transformFeedback |
| must: be enabled |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02356]] |
| pname:firstBinding must: be less than |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357]] |
| The sum of pname:firstBinding and pname:bindingCount must: be less than |
| or equal to |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02358]] |
| All elements of pname:pOffsets must: be less than the size of the |
| corresponding element in pname:pBuffers |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02359]] |
| All elements of pname:pOffsets must: be a multiple of 4 |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02360]] |
| All elements of pname:pBuffers must: have been created with the |
| ename:VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT flag |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pSize-02361]] |
| If the optional pname:pSize array is specified, each element of |
| pname:pSizes must: either be ename:VK_WHOLE_SIZE, or be less than or |
| equal to |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBufferSize |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pSizes-02362]] |
| All elements of pname:pSizes must: be either ename:VK_WHOLE_SIZE, or |
| less than or equal to the size of the corresponding buffer in |
| pname:pBuffers |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363]] |
| All elements of pname:pOffsets plus pname:pSizes, where the |
| pname:pSizes, element is not ename:VK_WHOLE_SIZE, must: be less than or |
| equal to the size of the corresponding buffer in pname:pBuffers |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02364]] |
| Each element of pname:pBuffers that is non-sparse must: be bound |
| completely and contiguously to a single sname:VkDeviceMemory object |
| * [[VUID-vkCmdBindTransformFeedbackBuffersEXT-None-02365]] |
| Transform feedback must: not be active when the |
| fname:vkCmdBindTransformFeedbackBuffersEXT command is recorded |
| **** |
| |
| include::{generated}/validity/protos/vkCmdBindTransformFeedbackBuffersEXT.adoc[] |
| -- |
| |
| [open,refpage='vkCmdBeginTransformFeedbackEXT',desc='Make transform feedback active in the command buffer',type='protos'] |
| -- |
| Transform feedback for specific transform feedback buffers is made active by |
| calling: |
| |
| include::{generated}/api/protos/vkCmdBeginTransformFeedbackEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:firstCounterBuffer is the index of the first transform feedback |
| buffer corresponding to pname:pCounterBuffers[0] and |
| pname:pCounterBufferOffsets[0]. |
| * pname:counterBufferCount is the size of the pname:pCounterBuffers and |
| pname:pCounterBufferOffsets arrays. |
| * pname:pCounterBuffers is `NULL` or a pointer to an array of |
| slink:VkBuffer handles to counter buffers. |
| Each buffer contains a 4 byte integer value representing the byte offset |
| from the start of the corresponding transform feedback buffer from where |
| to start capturing vertex data. |
| If the byte offset stored to the counter buffer location was done using |
| flink:vkCmdEndTransformFeedbackEXT it can be used to resume transform |
| feedback from the previous location. |
| If pname:pCounterBuffers is `NULL`, then transform feedback will start |
| capturing vertex data to byte offset zero in all bound transform |
| feedback buffers. |
| For each element of pname:pCounterBuffers that is dlink:VK_NULL_HANDLE, |
| transform feedback will start capturing vertex data to byte zero in the |
| corresponding bound transform feedback buffer. |
| * pname:pCounterBufferOffsets is `NULL` or a pointer to an array of |
| basetype:VkDeviceSize values specifying offsets within each of the |
| pname:pCounterBuffers where the counter values were previously written. |
| The location in each counter buffer at these offsets must: be large |
| enough to contain 4 bytes of data. |
| This data is the number of bytes captured by the previous transform |
| feedback to this buffer. |
| If pname:pCounterBufferOffsets is `NULL`, then it is assumed the offsets |
| are zero. |
| |
| The active transform feedback buffers will capture primitives emitted from |
| the corresponding code:XfbBuffer in the bound graphics pipeline. |
| Any code:XfbBuffer emitted that does not output to an active transform |
| feedback buffer will not be captured. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-transformFeedback-02366]] |
| sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:transformFeedback |
| must: be enabled |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-None-02367]] |
| Transform feedback must: not be active |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02368]] |
| pname:firstCounterBuffer must: be less than |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369]] |
| The sum of pname:firstCounterBuffer and pname:counterBufferCount must: |
| be less than or equal to |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-counterBufferCount-02607]] |
| If pname:counterBufferCount is not `0`, and pname:pCounterBuffers is not |
| `NULL`, pname:pCounterBuffers must: be a valid pointer to an array of |
| pname:counterBufferCount sname:VkBuffer handles that are either valid or |
| dlink:VK_NULL_HANDLE |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-pCounterBufferOffsets-02370]] |
| For each buffer handle in the array, if it is not dlink:VK_NULL_HANDLE |
| it must: reference a buffer large enough to hold 4 bytes at the |
| corresponding offset from the pname:pCounterBufferOffsets array |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffer-02371]] |
| If pname:pCounterBuffer is `NULL`, then pname:pCounterBufferOffsets |
| must: also be `NULL` |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffers-02372]] |
| For each buffer handle in the pname:pCounterBuffers array that is not |
| dlink:VK_NULL_HANDLE it must: have been created with a pname:usage value |
| containing |
| ename:VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-None-06233]] |
| A valid graphics pipeline must: be bound to |
| ename:VK_PIPELINE_BIND_POINT_GRAPHICS |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-None-04128]] |
| The last |
| <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>> of the bound graphics pipeline must: have been declared with the |
| code:Xfb execution mode |
| ifdef::VK_VERSION_1_1,VK_KHR_multiview[] |
| * [[VUID-vkCmdBeginTransformFeedbackEXT-None-02373]] |
| Transform feedback must: not be made active in a render pass instance |
| with multiview enabled |
| endif::VK_VERSION_1_1,VK_KHR_multiview[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdBeginTransformFeedbackEXT.adoc[] |
| -- |
| |
| [open,refpage='vkCmdEndTransformFeedbackEXT',desc='Make transform feedback inactive in the command buffer',type='protos'] |
| -- |
| Transform feedback for specific transform feedback buffers is made inactive |
| by calling: |
| |
| include::{generated}/api/protos/vkCmdEndTransformFeedbackEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:firstCounterBuffer is the index of the first transform feedback |
| buffer corresponding to pname:pCounterBuffers[0] and |
| pname:pCounterBufferOffsets[0]. |
| * pname:counterBufferCount is the size of the pname:pCounterBuffers and |
| pname:pCounterBufferOffsets arrays. |
| * pname:pCounterBuffers is `NULL` or a pointer to an array of |
| slink:VkBuffer handles to counter buffers. |
| The counter buffers are used to record the current byte positions of |
| each transform feedback buffer where the next vertex output data would |
| be captured. |
| This can: be used by a subsequent flink:vkCmdBeginTransformFeedbackEXT |
| call to resume transform feedback capture from this position. |
| It can also be used by flink:vkCmdDrawIndirectByteCountEXT to determine |
| the vertex count of the draw call. |
| * pname:pCounterBufferOffsets is `NULL` or a pointer to an array of |
| basetype:VkDeviceSize values specifying offsets within each of the |
| pname:pCounterBuffers where the counter values can be written. |
| The location in each counter buffer at these offsets must: be large |
| enough to contain 4 bytes of data. |
| The data stored at this location is the byte offset from the start of |
| the transform feedback buffer binding where the next vertex data would |
| be written. |
| If pname:pCounterBufferOffsets is `NULL`, then it is assumed the offsets |
| are zero. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdEndTransformFeedbackEXT-transformFeedback-02374]] |
| sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:transformFeedback |
| must: be enabled |
| * [[VUID-vkCmdEndTransformFeedbackEXT-None-02375]] |
| Transform feedback must: be active |
| * [[VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02376]] |
| pname:firstCounterBuffer must: be less than |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers |
| * [[VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377]] |
| The sum of pname:firstCounterBuffer and pname:counterBufferCount must: |
| be less than or equal to |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBuffers |
| * [[VUID-vkCmdEndTransformFeedbackEXT-counterBufferCount-02608]] |
| If pname:counterBufferCount is not `0`, and pname:pCounterBuffers is not |
| `NULL`, pname:pCounterBuffers must: be a valid pointer to an array of |
| pname:counterBufferCount sname:VkBuffer handles that are either valid or |
| dlink:VK_NULL_HANDLE |
| * [[VUID-vkCmdEndTransformFeedbackEXT-pCounterBufferOffsets-02378]] |
| For each buffer handle in the array, if it is not dlink:VK_NULL_HANDLE |
| it must: reference a buffer large enough to hold 4 bytes at the |
| corresponding offset from the pname:pCounterBufferOffsets array |
| * [[VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffer-02379]] |
| If pname:pCounterBuffer is `NULL`, then pname:pCounterBufferOffsets |
| must: also be `NULL` |
| * [[VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffers-02380]] |
| For each buffer handle in the pname:pCounterBuffers array that is not |
| dlink:VK_NULL_HANDLE it must: have been created with a pname:usage value |
| containing |
| ename:VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT |
| **** |
| |
| include::{generated}/validity/protos/vkCmdEndTransformFeedbackEXT.adoc[] |
| -- |
| endif::VK_EXT_transform_feedback[] |
| |
| |
| ifdef::VK_NV_viewport_swizzle[] |
| [[vertexpostproc-viewport-swizzle]] |
| == Viewport Swizzle |
| |
| [open,refpage='VkPipelineViewportSwizzleStateCreateInfoNV',desc='Structure specifying swizzle applied to primitive clip coordinates',type='structs'] |
| -- |
| Each primitive sent to a given viewport has a swizzle and optional: negation |
| applied to its clip coordinates. |
| The swizzle that is applied depends on the viewport index, and is controlled |
| by the sname:VkPipelineViewportSwizzleStateCreateInfoNV pipeline state: |
| |
| include::{generated}/api/structs/VkPipelineViewportSwizzleStateCreateInfoNV.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is reserved for future use. |
| * pname:viewportCount is the number of viewport swizzles used by the |
| pipeline. |
| * pname:pViewportSwizzles is a pointer to an array of |
| slink:VkViewportSwizzleNV structures, defining the viewport swizzles. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineViewportSwizzleStateCreateInfoNV-viewportCount-01215]] |
| pname:viewportCount must: be greater than or equal to the |
| pname:viewportCount set in sname:VkPipelineViewportStateCreateInfo |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineViewportSwizzleStateCreateInfoNV.adoc[] |
| -- |
| |
| [open,refpage='VkPipelineViewportSwizzleStateCreateFlagsNV',desc='Reserved for future use',type='flags'] |
| -- |
| include::{generated}/api/flags/VkPipelineViewportSwizzleStateCreateFlagsNV.adoc[] |
| |
| tname:VkPipelineViewportSwizzleStateCreateFlagsNV is a bitmask type for |
| setting a mask, but is currently reserved for future use. |
| -- |
| |
| The sname:VkPipelineViewportSwizzleStateCreateInfoNV state is set by adding |
| this structure to the pname:pNext chain of a |
| sname:VkPipelineViewportStateCreateInfo structure and setting the graphics |
| pipeline state with flink:vkCreateGraphicsPipelines. |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| [open,refpage='vkCmdSetViewportSwizzleNV',desc='Specify the viewport swizzle state dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the viewport swizzle state, |
| call: |
| |
| include::{generated}/api/protos/vkCmdSetViewportSwizzleNV.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:firstViewport is the index of the first viewport whose parameters |
| are updated by the command. |
| * pname:viewportCount is the number of viewports whose parameters are |
| updated by the command. |
| * pname:pViewportSwizzles is a pointer to an array of |
| slink:VkViewportSwizzleNV structures specifying viewport swizzles. |
| |
| This command sets the viewport swizzle state for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineViewportSwizzleStateCreateInfoNV::pname:viewportCount, and |
| slink:VkPipelineViewportSwizzleStateCreateInfoNV::pname:pViewportSwizzles |
| values used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetViewportSwizzleNV |
| :requiredfeature: extendedDynamicState3ViewportSwizzle |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetViewportSwizzleNV.adoc[] |
| -- |
| |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| Each viewport specified from 0 to pname:viewportCount - 1 has its x,y,z,w |
| swizzle state set to the corresponding pname:x, pname:y, pname:z and pname:w |
| in the slink:VkViewportSwizzleNV structure. |
| Each component is of type elink:VkViewportCoordinateSwizzleNV, which |
| determines the type of swizzle for that component. |
| The value of pname:x computes the new x component of the position as: |
| |
| [source,c] |
| ---- |
| if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV) x' = x; |
| if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV) x' = -x; |
| if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV) x' = y; |
| if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV) x' = -y; |
| if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV) x' = z; |
| if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV) x' = -z; |
| if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV) x' = w; |
| if (x == VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV) x' = -w; |
| ---- |
| |
| Similar selections are performed for the pname:y, pname:z, and pname:w |
| coordinates. |
| This swizzling is applied before clipping and perspective divide. |
| If the swizzle for an active viewport index is not specified, the swizzle |
| for pname:x is ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, pname:y |
| is ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV, pname:z is |
| ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV and pname:w is |
| ename:VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV. |
| |
| Viewport swizzle parameters are specified by setting the pname:pNext pointer |
| of sname:VkGraphicsPipelineCreateInfo to point to a |
| sname:VkPipelineViewportSwizzleStateCreateInfoNV structure. |
| slink:VkPipelineViewportSwizzleStateCreateInfoNV uses |
| sname:VkViewportSwizzleNV to set the viewport swizzle parameters. |
| |
| [open,refpage='VkViewportSwizzleNV',desc='Structure specifying a viewport swizzle',type='structs'] |
| -- |
| The sname:VkViewportSwizzleNV structure is defined as: |
| |
| include::{generated}/api/structs/VkViewportSwizzleNV.adoc[] |
| |
| * pname:x is a elink:VkViewportCoordinateSwizzleNV value specifying the |
| swizzle operation to apply to the x component of the primitive |
| * pname:y is a elink:VkViewportCoordinateSwizzleNV value specifying the |
| swizzle operation to apply to the y component of the primitive |
| * pname:z is a elink:VkViewportCoordinateSwizzleNV value specifying the |
| swizzle operation to apply to the z component of the primitive |
| * pname:w is a elink:VkViewportCoordinateSwizzleNV value specifying the |
| swizzle operation to apply to the w component of the primitive |
| |
| include::{generated}/validity/structs/VkViewportSwizzleNV.adoc[] |
| -- |
| |
| [open,refpage='VkViewportCoordinateSwizzleNV',desc='Specify how a viewport coordinate is swizzled',type='enums'] |
| -- |
| Possible values of the slink:VkViewportSwizzleNV::pname:x, pname:y, pname:z, |
| and pname:w members, specifying swizzling of the corresponding components of |
| primitives, are: |
| |
| include::{generated}/api/enums/VkViewportCoordinateSwizzleNV.adoc[] |
| |
| These values are described in detail in <<vertexpostproc-viewport-swizzle, |
| Viewport Swizzle>>. |
| -- |
| endif::VK_NV_viewport_swizzle[] |
| |
| |
| [[vertexpostproc-flatshading]] |
| == Flat Shading |
| |
| _Flat shading_ a vertex output attribute means to assign all vertices of the |
| primitive the same value for that output. |
| The output values assigned are those of the _provoking vertex_ of the |
| primitive. |
| Flat shading is applied to those vertex attributes that |
| <<interfaces-iointerfaces-matching,match>> fragment input attributes which |
| are decorated as code:Flat. |
| |
| If neither |
| ifdef::VK_EXT_mesh_shader,VK_NV_mesh_shader[] |
| <<mesh, mesh>>, |
| endif::VK_EXT_mesh_shader,VK_NV_mesh_shader[] |
| <<geometry,geometry>> nor <<tessellation,tessellation shading>> is active, |
| the provoking vertex is determined by the <<drawing-primitive-topologies, |
| primitive topology>> defined by |
| slink:VkPipelineInputAssemblyStateCreateInfo:pname:topology used to execute |
| the <<drawing,drawing command>>. |
| |
| ifdef::VK_NV_mesh_shader[] |
| If a shader using code:MeshNV {ExecutionModel} is active, the provoking |
| vertex is determined by the <<drawing-primitive-topologies, primitive |
| topology>> defined by the <<drawing-point-lists, code:OutputPoints>>, |
| <<drawing-line-lists, code:OutputLinesNV>>, or <<drawing-triangle-lists, |
| code:OutputTrianglesNV>> execution mode. |
| endif::VK_NV_mesh_shader[] |
| |
| ifdef::VK_EXT_mesh_shader[] |
| If a shader using code:MeshEXT {ExecutionModel} is active, the provoking |
| vertex is determined by the <<drawing-primitive-topologies, primitive |
| topology>> defined by the <<drawing-point-lists, code:OutputPoints>>, |
| <<drawing-line-lists, code:OutputLinesEXT>>, or <<drawing-triangle-lists, |
| code:OutputTrianglesEXT>> execution mode. |
| endif::VK_EXT_mesh_shader[] |
| |
| If <<geometry,geometry shading>> is active, the provoking vertex is |
| determined by the <<drawing-primitive-topologies, primitive topology>> |
| defined by the <<drawing-point-lists, code:OutputPoints>>, |
| <<drawing-line-strips, code:OutputLineStrips>>, or |
| <<drawing-triangle-strips, code:OutputTriangleStrips>> execution mode. |
| |
| If <<tessellation,tessellation shading>> is active but <<geometry,geometry |
| shading>> is not, the provoking vertex may: be any of the vertices in each |
| primitive. |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| [open,refpage='VkPipelineRasterizationProvokingVertexStateCreateInfoEXT',desc='Structure specifying provoking vertex mode used by a graphics pipeline',type='structs'] |
| -- |
| For a given primitive topology, the pipeline's provoking vertex mode |
| determines which vertex is the provoking vertex. |
| To specify the provoking vertex mode, include a |
| sname:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT structure in |
| the slink:VkPipelineRasterizationStateCreateInfo::pname:pNext chain when |
| creating the pipeline. |
| |
| The sname:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT structure |
| is defined as: |
| |
| include::{generated}/api/structs/VkPipelineRasterizationProvokingVertexStateCreateInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:provokingVertexMode is a elink:VkProvokingVertexModeEXT value |
| selecting the provoking vertex mode. |
| |
| If this struct is not provided when creating the pipeline, the pipeline will |
| use the ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT mode. |
| |
| If the <<limits-provokingVertexModePerPipeline, |
| pname:provokingVertexModePerPipeline>> limit is ename:VK_FALSE, then all |
| pipelines bound within a render pass instance must: have the same |
| pname:provokingVertexMode. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineRasterizationProvokingVertexStateCreateInfoEXT-provokingVertexMode-04883]] |
| If pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, then the |
| <<features-provokingVertexLast, pname:provokingVertexLast>> feature |
| must: be enabled |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineRasterizationProvokingVertexStateCreateInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkProvokingVertexModeEXT',desc='Specify which vertex in a primitive is the provoking vertex',type='enums'] |
| -- |
| Possible values of |
| slink:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::pname:provokingVertexMode |
| are: |
| |
| include::{generated}/api/enums/VkProvokingVertexModeEXT.adoc[] |
| |
| * ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT specifies that the |
| provoking vertex is the first non-adjacency vertex in the list of |
| vertices used by a primitive. |
| * ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT specifies that the |
| provoking vertex is the last non-adjacency vertex in the list of |
| vertices used by a primitive. |
| |
| These modes are described more precisely in |
| <<drawing-primitive-topologies,Primitive Topologies>>. |
| -- |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| [open,refpage='vkCmdSetProvokingVertexModeEXT',desc='Specify the provoking vertex mode dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the |
| pname:provokingVertexMode state, call: |
| |
| include::{generated}/api/protos/vkCmdSetProvokingVertexModeEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:provokingVertexMode specifies the pname:provokingVertexMode state. |
| |
| This command sets the pname:provokingVertexMode state for subsequent drawing |
| commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::pname:provokingVertexMode |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetProvokingVertexModeEXT |
| :requiredfeature: extendedDynamicState3ProvokingVertexMode |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| * [[VUID-vkCmdSetProvokingVertexModeEXT-provokingVertexMode-07447]] |
| If pname:provokingVertexMode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, then the |
| <<features-provokingVertexLast, pname:provokingVertexLast>> feature |
| must: be enabled |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetProvokingVertexModeEXT.adoc[] |
| -- |
| |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| endif::VK_EXT_provoking_vertex[] |
| |
| |
| [[vertexpostproc-clipping]] |
| == Primitive Clipping |
| |
| Primitives are culled against the _cull volume_ and then clipped to the |
| _clip volume_. |
| In clip coordinates, the _view volume_ is defined by: |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| \begin{array}{c} |
| -w_c \leq x_c \leq w_c \\ |
| -w_c \leq y_c \leq w_c \\ |
| z_m \leq z_c \leq w_c |
| \end{array} |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| where |
| ifdef::VK_EXT_depth_clip_control[] |
| if |
| slink:VkPipelineViewportDepthClipControlCreateInfoEXT::pname:negativeOneToOne |
| is ename:VK_TRUE [eq]#z~m~# is equal to [eq]#-w~c~# otherwise |
| endif::VK_EXT_depth_clip_control[] |
| [eq]#z~m~# is equal to zero. |
| |
| This view volume can: be further restricted by as many as |
| sname:VkPhysicalDeviceLimits::pname:maxClipDistances client-defined |
| half-spaces. |
| |
| The cull volume is the intersection of up to |
| sname:VkPhysicalDeviceLimits::pname:maxCullDistances client-defined |
| half-spaces (if no client-defined cull half-spaces are enabled, culling |
| against the cull volume is skipped). |
| |
| A shader must: write a single cull distance for each enabled cull half-space |
| to elements of the code:CullDistance array. |
| If the cull distance for any enabled cull half-space is negative for all of |
| the vertices of the primitive under consideration, the primitive is |
| discarded. |
| Otherwise the primitive is clipped against the clip volume as defined below. |
| |
| The clip volume is the intersection of up to |
| sname:VkPhysicalDeviceLimits::pname:maxClipDistances client-defined |
| half-spaces with the view volume (if no client-defined clip half-spaces are |
| enabled, the clip volume is the view volume). |
| |
| A shader must: write a single clip distance for each enabled clip half-space |
| to elements of the code:ClipDistance array. |
| Clip half-space [eq]#i# is then given by the set of points satisfying the |
| inequality |
| |
| {empty}:: [eq]#c~i~(**P**) {geq} 0# |
| |
| where [eq]#c~i~(**P**)# is the clip distance [eq]#i# at point [eq]#**P**#. |
| For point primitives, [eq]#c~i~(**P**)# is simply the clip distance for the |
| vertex in question. |
| For line and triangle primitives, per-vertex clip distances are interpolated |
| using a weighted mean, with weights derived according to the algorithms |
| described in sections <<primsrast-lines-basic,Basic Line Segment |
| Rasterization>> and <<primsrast-polygons-basic,Basic Polygon |
| Rasterization>>, using the perspective interpolation equations. |
| |
| The number of client-defined clip and cull half-spaces that are enabled is |
| determined by the explicit size of the built-in arrays code:ClipDistance and |
| code:CullDistance, respectively, declared as an output in the interface of |
| the entry point of the final shader stage before clipping. |
| |
| ifdef::VK_EXT_depth_clip_enable[] |
| If slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT is present in |
| the graphics pipeline state then depth clipping is disabled if |
| slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT::pname:depthClipEnable |
| is ename:VK_FALSE. |
| Otherwise, if slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT is |
| not present, depth clipping is disabled when |
| slink:VkPipelineRasterizationStateCreateInfo::pname:depthClampEnable is |
| ename:VK_TRUE. |
| endif::VK_EXT_depth_clip_enable[] |
| ifndef::VK_EXT_depth_clip_enable[] |
| Depth clamping is enabled or disabled via the pname:depthClampEnable enable |
| of the slink:VkPipelineRasterizationStateCreateInfo structure. |
| Depth clipping is disabled when pname:depthClampEnable is ename:VK_TRUE. |
| endif::VK_EXT_depth_clip_enable[] |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| [open,refpage='vkCmdSetDepthClampEnableEXT',desc='Specify dynamically whether depth clamping is enabled in the command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> enable or disable depth |
| clamping, call: |
| |
| include::{generated}/api/protos/vkCmdSetDepthClampEnableEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:depthClampEnable specifies whether depth clamping is enabled. |
| |
| This command sets whether depth clamping is enabled or disabled for |
| subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:depthClampEnable value |
| used to create the currently active pipeline. |
| |
| If the depth clamping state is changed dynamically, and the pipeline was not |
| created with ename:VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT enabled, then |
| depth clipping is enabled when depth clamping is disabled and vice versa. |
| |
| :refpage: vkCmdSetDepthClampEnableEXT |
| :requiredfeature: extendedDynamicState3DepthClampEnable |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| * [[VUID-vkCmdSetDepthClampEnableEXT-depthClamp-07449]] |
| If the <<features-depthClamp, pname:depthClamp>> feature is not enabled, |
| pname:depthClampEnable must be ename:VK_FALSE |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetDepthClampEnableEXT.adoc[] |
| -- |
| |
| ifdef::VK_EXT_depth_clip_enable[] |
| [open,refpage='vkCmdSetDepthClipEnableEXT',desc='Specify dynamically whether depth clipping is enabled in the command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> enable or disable depth |
| clipping, call: |
| |
| include::{generated}/api/protos/vkCmdSetDepthClipEnableEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:depthClipEnable specifies whether depth clipping is enabled. |
| |
| This command sets whether depth clipping is enabled or disabled for |
| subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT::pname:depthClipEnable |
| value used to create the currently active pipeline, or is set to the inverse |
| of slink:VkPipelineRasterizationStateCreateInfo::pname:depthClampEnable if |
| sname:VkPipelineRasterizationDepthClipStateCreateInfoEXT is not specified. |
| |
| :refpage: vkCmdSetDepthClipEnableEXT |
| :requiredfeature: extendedDynamicState3DepthClipEnable |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| * [[VUID-vkCmdSetDepthClipEnableEXT-depthClipEnable-07451]] |
| The <<features-depthClipEnable, pname:depthClipEnable>> feature must: be |
| enabled |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetDepthClipEnableEXT.adoc[] |
| -- |
| endif::VK_EXT_depth_clip_enable[] |
| |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| When depth clipping is disabled, the plane equation |
| |
| {empty}:: [eq]#z~m~ {leq} z~c~ {leq} w~c~# |
| |
| (see the clip volume definition above) is ignored by view volume clipping |
| (effectively, there is no near or far plane clipping). |
| |
| If the primitive under consideration is a point or line segment, then |
| clipping passes it unchanged if its vertices lie entirely within the clip |
| volume. |
| |
| ifndef::VK_VERSION_1_1,VK_KHR_maintenance2[] |
| If a point's vertex lies outside of the clip volume, the entire primitive |
| may: be discarded. |
| endif::VK_VERSION_1_1,VK_KHR_maintenance2[] |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_maintenance2[] |
| [open,refpage='VkPointClippingBehavior',desc='Enum specifying the point clipping behavior',type='enums'] |
| -- |
| Possible values of |
| slink:VkPhysicalDevicePointClippingProperties::pname:pointClippingBehavior, |
| specifying clipping behavior of a point primitive whose vertex lies outside |
| the clip volume, are: |
| |
| include::{generated}/api/enums/VkPointClippingBehavior.adoc[] |
| |
| ifdef::VK_KHR_maintenance2[] |
| or the equivalent |
| |
| include::{generated}/api/enums/VkPointClippingBehaviorKHR.adoc[] |
| endif::VK_KHR_maintenance2[] |
| |
| * ename:VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES specifies that the |
| primitive is discarded if the vertex lies outside any clip plane, |
| including the planes bounding the view volume. |
| * ename:VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY specifies that |
| the primitive is discarded only if the vertex lies outside any user clip |
| plane. |
| -- |
| endif::VK_VERSION_1_1,VK_KHR_maintenance2[] |
| |
| If either of a line segment's vertices lie outside of the clip volume, the |
| line segment may: be clipped, with new vertex coordinates computed for each |
| vertex that lies outside the clip volume. |
| A clipped line segment endpoint lies on both the original line segment and |
| the boundary of the clip volume. |
| |
| This clipping produces a value, [eq]#0 {leq} t {leq} 1#, for each clipped |
| vertex. |
| If the coordinates of a clipped vertex are [eq]#**P**# and the unclipped |
| line segment's vertex coordinates are [eq]#**P**~1~# and [eq]#**P**~2~#, |
| then [eq]#t# satisfies the following equation |
| |
| {empty}:: [eq]#**P** = t **P**~1~ {plus} (1-t) **P**~2~#. |
| |
| [eq]#t# is used to clip vertex output attributes as described in |
| <<vertexpostproc-clipping-shader-outputs,Clipping Shader Outputs>>. |
| |
| If the primitive is a polygon, it passes unchanged if every one of its edges |
| lies entirely inside the clip volume, and is either clipped or discarded |
| otherwise. |
| If the edges of the polygon intersect the boundary of the clip volume, the |
| intersecting edges are reconnected by new edges that lie along the boundary |
| of the clip volume - in some cases requiring the introduction of new |
| vertices into a polygon. |
| |
| If a polygon intersects an edge of the clip volume's boundary, the clipped |
| polygon must: include a point on this boundary edge. |
| |
| Primitives rendered with user-defined half-spaces must: satisfy a |
| complementarity criterion. |
| Suppose a series of primitives is drawn where each vertex [eq]#i# has a |
| single specified clip distance [eq]#d~i~# (or a number of similarly |
| specified clip distances, if multiple half-spaces are enabled). |
| Next, suppose that the same series of primitives are drawn again with each |
| such clip distance replaced by [eq]#-d~i~# (and the graphics pipeline is |
| otherwise the same). |
| In this case, primitives must: not be missing any pixels, and pixels must: |
| not be drawn twice in regions where those primitives are cut by the clip |
| planes. |
| |
| ifdef::VK_EXT_depth_clip_control[] |
| [open,refpage='VkPipelineViewportDepthClipControlCreateInfoEXT',desc='Structure specifying parameters of a newly created pipeline depth clip control state',type='structs'] |
| -- |
| The sname:VkPipelineViewportDepthClipControlCreateInfoEXT structure is |
| defined as: |
| |
| include::{generated}/api/structs/VkPipelineViewportDepthClipControlCreateInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:negativeOneToOne sets the [eq]#z~m~# in the _view volume_ to |
| [eq]#-w~c~# |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineViewportDepthClipControlCreateInfoEXT-negativeOneToOne-06470]] |
| If <<features-depthClipControl, pname:depthClipControl>> is not enabled, |
| pname:negativeOneToOne must: be ename:VK_FALSE |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineViewportDepthClipControlCreateInfoEXT.adoc[] |
| -- |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetDepthClipNegativeOneToOneEXT',desc='Specify the negative one to one depth clip mode dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> pname:negativeOneToOne, |
| call: |
| |
| include::{generated}/api/protos/vkCmdSetDepthClipNegativeOneToOneEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:negativeOneToOne specifies the pname:negativeOneToOne state. |
| |
| This command sets the pname:negativeOneToOne state for subsequent drawing |
| commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineViewportDepthClipControlCreateInfoEXT::pname:negativeOneToOne |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetDepthClipNegativeOneToOneEXT |
| :requiredfeature: extendedDynamicState3DepthClipNegativeOneToOne |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| * [[VUID-vkCmdSetDepthClipNegativeOneToOneEXT-depthClipControl-07453]] |
| The <<features-depthClipControl, pname:depthClipControl>> feature must: |
| be enabled |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetDepthClipNegativeOneToOneEXT.adoc[] |
| -- |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| endif::VK_EXT_depth_clip_control[] |
| |
| |
| [[vertexpostproc-clipping-shader-outputs]] |
| == Clipping Shader Outputs |
| |
| Next, vertex output attributes are clipped. |
| The output values associated with a vertex that lies within the clip volume |
| are unaffected by clipping. |
| If a primitive is clipped, however, the output values assigned to vertices |
| produced by clipping are clipped. |
| |
| Let the output values assigned to the two vertices [eq]#**P**~1~# and |
| [eq]#**P**~2~# of an unclipped edge be [eq]#**c**~1~# and [eq]#**c**~2~#. |
| The value of [eq]#t# (see <<vertexpostproc-clipping,Primitive Clipping>>) |
| for a clipped point [eq]#**P**# is used to obtain the output value |
| associated with [eq]#**P**# as |
| |
| {empty}:: [eq]#**c** = t **c**~1~ {plus} (1-t) **c**~2~#. |
| |
| (Multiplying an output value by a scalar means multiplying each of _x_, _y_, |
| _z_, and _w_ by the scalar.) |
| |
| Since this computation is performed in clip space before division by |
| [eq]#w~c~#, clipped output values are perspective-correct. |
| |
| Polygon clipping creates a clipped vertex along an edge of the clip volume's |
| boundary. |
| This situation is handled by noting that polygon clipping proceeds by |
| clipping against one half-space at a time. |
| Output value clipping is done in the same way, so that clipped points always |
| occur at the intersection of polygon edges (possibly already clipped) with |
| the clip volume's boundary. |
| |
| For vertex output attributes whose matching fragment input attributes are |
| decorated with code:NoPerspective, the value of [eq]#t# used to obtain the |
| output value associated with [eq]#**P**# will be adjusted to produce results |
| that vary linearly in framebuffer space. |
| |
| Output attributes of integer or unsigned integer type must: always be flat |
| shaded. |
| Flat shaded attributes are constant over the primitive being rasterized (see |
| <<primsrast-lines-basic,Basic Line Segment Rasterization>> and |
| <<primsrast-polygons-basic,Basic Polygon Rasterization>>), and no |
| interpolation is performed. |
| The output value [eq]#**c**# is taken from either [eq]#**c**~1~# or |
| [eq]#**c**~2~#, since flat shading has already occurred and the two values |
| are identical. |
| |
| ifdef::VK_NV_clip_space_w_scaling[] |
| include::{chapters}/VK_NV_clip_space_w_scaling/vertexpostproc.adoc[] |
| endif::VK_NV_clip_space_w_scaling[] |
| |
| |
| [[vertexpostproc-coord-transform]] |
| == Coordinate Transformations |
| |
| _Clip coordinates_ for a vertex result from shader execution, which yields a |
| vertex coordinate code:Position. |
| |
| Perspective division on clip coordinates yields _normalized device |
| coordinates_, followed by a _viewport_ transformation (see |
| <<vertexpostproc-viewport,Controlling the Viewport>>) to convert these |
| coordinates into _framebuffer coordinates_. |
| |
| If a vertex in clip coordinates has a position given by |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| \left(\begin{array}{c} |
| x_c \\ |
| y_c \\ |
| z_c \\ |
| w_c |
| \end{array}\right) |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| then the vertex's normalized device coordinates are |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| \left( |
| \begin{array}{c} |
| x_d \\ |
| y_d \\ |
| z_d |
| \end{array} |
| \right) = |
| \left( |
| \begin{array}{c} |
| \frac{x_c}{w_c} \\ |
| \frac{y_c}{w_c} \\ |
| \frac{z_c}{w_c} |
| \end{array} |
| \right) |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| |
| ifdef::VK_QCOM_render_pass_transform[] |
| [[vertexpostproc-renderpass-transform]] |
| == Render Pass Transform |
| |
| A _render pass transform_ can: be enabled for render pass instances. |
| The clip coordinates [eq]#(x~c~, y~c~)# that result from vertex shader |
| execution are transformed by a rotation of 0, 90, 180, or 270 degrees in the |
| XY plane, centered at the origin. |
| |
| When _Render pass transform_ is enabled, the transform applies to all |
| primitives for all subpasses of the render pass. |
| The transformed vertex in clip coordinates has a position given by |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| \left( |
| \begin{array}{c} |
| x_{c_{trans}} \\ |
| y_{c_{trans}} \\ |
| z_{c_{trans}} |
| \end{array} |
| \right) = |
| \left( |
| \begin{array}{c} |
| x_{c} \cos \theta - y_{c} \sin \theta \\ |
| x_{c} \sin \theta + y_{c} \cos \theta \\ |
| z_c |
| \end{array} |
| \right) |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| where |
| |
| * _[eq]#{theta}#_ is 0 degrees for |
| ename:VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR |
| * _[eq]#{theta}#_ is 90 degrees for |
| ename:VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR |
| * _[eq]#{theta}#_ is 180 degrees for |
| ename:VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR |
| * _[eq]#{theta}#_ is 270 degrees for |
| ename:VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR |
| |
| |
| The transformed vertex's normalized device coordinates are |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| \left( |
| \begin{array}{c} |
| x_d \\ |
| y_d \\ |
| z_d |
| \end{array} |
| \right) = |
| \left( |
| \begin{array}{c} |
| \frac{x_{c_{trans}}}{w_c} \\ |
| \frac{y_{c_{trans}}}{w_c} \\ |
| \frac{z_{c_{trans}}}{w_c} |
| \end{array} |
| \right) |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| |
| When render pass transform is enabled for a render pass instance, the |
| following additional features are enabled: |
| |
| * Each slink:VkViewport specified by either |
| slink:VkPipelineViewportStateCreateInfo::pname:pViewports or |
| flink:vkCmdSetViewport will have its width/height [eq]#(p~x~, p~y~)# and |
| its center [eq]#(o~x~, o~y~)# similarly transformed by the |
| implementation. |
| * Each scissor specified by |
| slink:VkPipelineViewportStateCreateInfo::pname:pScissors or |
| flink:vkCmdSetScissor will have its [eq]#(offset~x~, offset~y~)# and |
| [eq]#(extent~x~, extent~y~)# similarly transformed by the |
| implementation. |
| * The pname:renderArea specified in |
| slink:VkCommandBufferInheritanceRenderPassTransformInfoQCOM and |
| slink:VkRenderPassBeginInfo will be similarly transformed by the |
| implementation. |
| * The [eq]#(x, y)# components of shader variables with built-in |
| decorations code:FragCoord, code:SamplePosition, or code:PointCoord will |
| be similarly transformed by the implementation. |
| * The [eq]#(x,y)# components of the code:offset operand of the |
| code:InterpolateAtOffset extended instruction will be similarly |
| transformed by the implementation. |
| * The values returned by SPIR-V <<shaders-derivative-operations, |
| derivative instructions>> code:OpDPdx, code:OpDPdy, code:OpDPdxCourse, |
| code:OpDPdyCourse, code:OpDPdxFine, code:OpDPdyFine will be similarly |
| transformed by the implementation. |
| |
| |
| The net result of the above, is that applications can: act as if rendering |
| to a framebuffer oriented with the |
| slink:VkSurfaceCapabilitiesKHR::pname:currentTransform. |
| In other words, applications can: act as if the presentation engine will be |
| performing the transformation of the swapchain image after rendering and |
| prior to presentation to the user. |
| In fact, the transformation of the various items cited above are being |
| handled by the implementation as the rendering takes place. |
| |
| endif::VK_QCOM_render_pass_transform[] |
| |
| |
| [[vertexpostproc-viewport]] |
| == Controlling the Viewport |
| |
| The viewport transformation is determined by the selected viewport's width |
| and height in pixels, [eq]#p~x~# and [eq]#p~y~#, respectively, and its |
| center [eq]#(o~x~, o~y~)# (also in pixels), as well as its depth range min |
| and max determining a depth range scale value [eq]#p~z~# and a depth range |
| bias value [eq]#o~z~# (defined below). |
| The vertex's framebuffer coordinates [eq]#(x~f~, y~f~, z~f~)# are given by |
| |
| {empty}:: [eq]#x~f~ = (p~x~ / 2) x~d~ {plus} o~x~# |
| {empty}:: [eq]#y~f~ = (p~y~ / 2) y~d~ {plus} o~y~# |
| {empty}:: [eq]#z~f~ = p~z~ {times} z~d~ {plus} o~z~# |
| |
| Multiple viewports are available, numbered zero up to |
| sname:VkPhysicalDeviceLimits::pname:maxViewports minus one. |
| The number of viewports used by a pipeline is controlled by the |
| pname:viewportCount member of the sname:VkPipelineViewportStateCreateInfo |
| structure used in pipeline creation. |
| |
| [eq]#x~f~# and [eq]#y~f~# have limited precision, where the number of |
| fractional bits retained is specified by |
| sname:VkPhysicalDeviceLimits::pname:subPixelPrecisionBits. |
| ifdef::VK_EXT_line_rasterization[] |
| When rasterizing <<primsrast-lines,line segments>>, the number of fractional |
| bits is specified by |
| sname:VkPhysicalDeviceLineRasterizationPropertiesEXT::pname:lineSubPixelPrecisionBits. |
| endif::VK_EXT_line_rasterization[] |
| |
| [open,refpage='VkPipelineViewportStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline viewport state',type='structs'] |
| -- |
| The sname:VkPipelineViewportStateCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkPipelineViewportStateCreateInfo.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is reserved for future use. |
| * pname:viewportCount is the number of viewports used by the pipeline. |
| * pname:pViewports is a pointer to an array of slink:VkViewport |
| structures, defining the viewport transforms. |
| If the viewport state is dynamic, this member is ignored. |
| * pname:scissorCount is the number of <<fragops-scissor,scissors>> and |
| must: match the number of viewports. |
| * pname:pScissors is a pointer to an array of slink:VkRect2D structures |
| defining the rectangular bounds of the scissor for the corresponding |
| viewport. |
| If the scissor state is dynamic, this member is ignored. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216]] |
| If the <<features-multiViewport, pname:multiViewport>> feature is not |
| enabled, pname:viewportCount must: not be greater than `1` |
| * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217]] |
| If the <<features-multiViewport, pname:multiViewport>> feature is not |
| enabled, pname:scissorCount must: not be greater than `1` |
| * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218]] |
| pname:viewportCount must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxViewports |
| * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219]] |
| pname:scissorCount must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxViewports |
| * [[VUID-VkPipelineViewportStateCreateInfo-x-02821]] |
| The pname:x and pname:y members of pname:offset member of any element of |
| pname:pScissors must: be greater than or equal to `0` |
| * [[VUID-VkPipelineViewportStateCreateInfo-offset-02822]] |
| Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# must: not |
| cause a signed integer addition overflow for any element of |
| pname:pScissors |
| * [[VUID-VkPipelineViewportStateCreateInfo-offset-02823]] |
| Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# must: |
| not cause a signed integer addition overflow for any element of |
| pname:pScissors |
| * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-04134]] |
| If pname:scissorCount and pname:viewportCount are both not dynamic, then |
| pname:scissorCount and pname:viewportCount must: be identical |
| ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength]] |
| pname:viewportCount must: be greater than `0` |
| * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength]] |
| pname:scissorCount must: be greater than `0` |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| * [[VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135]] |
| If the graphics pipeline is being created with |
| ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT set then pname:viewportCount |
| must: be `0`, otherwise it must: be greater than `0` |
| * [[VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136]] |
| If the graphics pipeline is being created with |
| ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT set then pname:scissorCount |
| must: be `0`, otherwise it must: be greater than `0` |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| ifdef::VK_NV_clip_space_w_scaling[] |
| * [[VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726]] |
| If the pname:viewportWScalingEnable member of a |
| slink:VkPipelineViewportWScalingStateCreateInfoNV structure included in |
| the pname:pNext chain is ename:VK_TRUE, the pname:viewportCount member |
| of the slink:VkPipelineViewportWScalingStateCreateInfoNV structure must: |
| be greater than or equal to |
| slink:VkPipelineViewportStateCreateInfo::pname:viewportCount |
| endif::VK_NV_clip_space_w_scaling[] |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineViewportStateCreateInfo.adoc[] |
| -- |
| |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetViewportWithCount',desc='Set the viewport count and viewports dynamically for a command buffer',type='protos',alias='vkCmdSetViewportWithCountEXT'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the viewport count and |
| viewports, call: |
| |
| ifdef::VK_VERSION_1_3[] |
| include::{generated}/api/protos/vkCmdSetViewportWithCount.adoc[] |
| |
| ifdef::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[or the equivalent command] |
| endif::VK_VERSION_1_3[] |
| |
| ifdef::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| include::{generated}/api/protos/vkCmdSetViewportWithCountEXT.adoc[] |
| endif::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:viewportCount specifies the viewport count. |
| * pname:pViewports specifies the viewports to use for drawing. |
| |
| This command sets the viewport count and viewports state for subsequent |
| drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| Otherwise, this state is specified by the corresponding |
| slink:VkPipelineViewportStateCreateInfo::pname:viewportCount and |
| pname:pViewports values used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetViewportWithCount |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state_feature_common.adoc[] |
| * [[VUID-vkCmdSetViewportWithCount-viewportCount-03394]] |
| pname:viewportCount must: be between `1` and |
| sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive |
| * [[VUID-vkCmdSetViewportWithCount-viewportCount-03395]] |
| If the <<features-multiViewport, pname:multiViewport>> feature is not |
| enabled, pname:viewportCount must: be `1` |
| ifdef::VK_NV_inherited_viewport_scissor[] |
| * [[VUID-vkCmdSetViewportWithCount-commandBuffer-04819]] |
| pname:commandBuffer must: not have |
| slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D |
| enabled |
| endif::VK_NV_inherited_viewport_scissor[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetViewportWithCount.adoc[] |
| -- |
| |
| [open,refpage='vkCmdSetScissorWithCount',desc='Set the scissor count and scissor rectangular bounds dynamically for a command buffer',type='protos',alias='vkCmdSetScissorWithCountEXT'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the scissor count and |
| scissor rectangular bounds, call: |
| |
| ifdef::VK_VERSION_1_3[] |
| include::{generated}/api/protos/vkCmdSetScissorWithCount.adoc[] |
| |
| ifdef::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[or the equivalent command] |
| endif::VK_VERSION_1_3[] |
| |
| ifdef::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| include::{generated}/api/protos/vkCmdSetScissorWithCountEXT.adoc[] |
| endif::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:scissorCount specifies the scissor count. |
| * pname:pScissors specifies the scissors to use for drawing. |
| |
| This command sets the scissor count and scissor rectangular bounds state for |
| subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| Otherwise, this state is specified by the corresponding |
| slink:VkPipelineViewportStateCreateInfo::pname:scissorCount and |
| pname:pScissors values used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetScissorWithCount |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state_feature_common.adoc[] |
| * [[VUID-vkCmdSetScissorWithCount-scissorCount-03397]] |
| pname:scissorCount must: be between `1` and |
| sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive |
| * [[VUID-vkCmdSetScissorWithCount-scissorCount-03398]] |
| If the <<features-multiViewport, pname:multiViewport>> feature is not |
| enabled, pname:scissorCount must: be `1` |
| * [[VUID-vkCmdSetScissorWithCount-x-03399]] |
| The pname:x and pname:y members of pname:offset member of any element of |
| pname:pScissors must: be greater than or equal to `0` |
| * [[VUID-vkCmdSetScissorWithCount-offset-03400]] |
| Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# must: not |
| cause a signed integer addition overflow for any element of |
| pname:pScissors |
| * [[VUID-vkCmdSetScissorWithCount-offset-03401]] |
| Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# must: |
| not cause a signed integer addition overflow for any element of |
| pname:pScissors |
| ifdef::VK_NV_inherited_viewport_scissor[] |
| * [[VUID-vkCmdSetScissorWithCount-commandBuffer-04820]] |
| pname:commandBuffer must: not have |
| slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D |
| enabled |
| endif::VK_NV_inherited_viewport_scissor[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetScissorWithCount.adoc[] |
| -- |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| [open,refpage='VkPipelineViewportStateCreateFlags',desc='Reserved for future use',type='flags'] |
| -- |
| include::{generated}/api/flags/VkPipelineViewportStateCreateFlags.adoc[] |
| |
| tname:VkPipelineViewportStateCreateFlags is a bitmask type for setting a |
| mask, but is currently reserved for future use. |
| -- |
| |
| ifndef::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] |
| If a geometry shader is active and has an output variable decorated with |
| code:ViewportIndex, the viewport transformation uses the viewport |
| corresponding to the value assigned to code:ViewportIndex taken from an |
| implementation-dependent vertex of each primitive. |
| If code:ViewportIndex is outside the range zero to pname:viewportCount minus |
| one for a primitive, or if the geometry shader did not assign a value to |
| code:ViewportIndex for all vertices of a primitive due to flow control, the |
| values resulting from the viewport transformation of the vertices of such |
| primitives are undefined:. |
| If no geometry shader is active, or if the geometry shader does not have an |
| output decorated with code:ViewportIndex, the viewport numbered zero is used |
| by the viewport transformation. |
| endif::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] |
| |
| ifdef::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] |
| ifdef::VK_NV_viewport_array2[] |
| A _<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>>_ can: direct each primitive to zero or more viewports. |
| The destination viewports for a primitive are selected by the last active |
| <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>> that has an output variable decorated with code:ViewportIndex |
| (selecting a single viewport) or code:ViewportMaskNV (selecting multiple |
| viewports). |
| The viewport transform uses the viewport corresponding to either the value |
| assigned to code:ViewportIndex or one of the bits set in |
| code:ViewportMaskNV, and taken from an implementation-dependent vertex of |
| each primitive. |
| If code:ViewportIndex or any of the bits in code:ViewportMaskNV are outside |
| the range zero to pname:viewportCount minus one for a primitive, or if the |
| last active <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization |
| shader stage>> did not assign a value to either code:ViewportIndex or |
| code:ViewportMaskNV for all vertices of a primitive due to flow control, the |
| values resulting from the viewport transformation of the vertices of such |
| primitives are undefined:. |
| If the last <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization |
| shader stage>> does not have an output decorated with code:ViewportIndex or |
| code:ViewportMaskNV, the viewport numbered zero is used by the viewport |
| transformation. |
| endif::VK_NV_viewport_array2[] |
| ifndef::VK_NV_viewport_array2[] |
| A _<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>>_ can: direct each primitive to one of several viewports. |
| The destination viewport for a primitive is selected by the last active |
| <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>> that has an output variable decorated with code:ViewportIndex. |
| The viewport transform uses the viewport corresponding to the value assigned |
| to code:ViewportIndex, and taken from an implementation-dependent vertex of |
| each primitive. |
| If code:ViewportIndex is outside the range zero to pname:viewportCount minus |
| one for a primitive, or if the last active |
| <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>> did not assign a value to code:ViewportIndex for all vertices of a |
| primitive due to flow control, the values resulting from the viewport |
| transformation of the vertices of such primitives are undefined:. |
| If the last <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization |
| shader stage>> does not have an output decorated with code:ViewportIndex, |
| the viewport numbered zero is used by the viewport transformation. |
| endif::VK_NV_viewport_array2[] |
| endif::VK_VERSION_1_2,VK_EXT_shader_viewport_index_layer,VK_NV_viewport_array2[] |
| |
| A single vertex can: be used in more than one individual primitive, in |
| primitives such as ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP. |
| In this case, the viewport transformation is applied separately for each |
| primitive. |
| |
| [open,refpage='vkCmdSetViewport',desc='Set the viewport dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the viewport transformation |
| parameters, call: |
| |
| include::{generated}/api/protos/vkCmdSetViewport.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:firstViewport is the index of the first viewport whose parameters |
| are updated by the command. |
| * pname:viewportCount is the number of viewports whose parameters are |
| updated by the command. |
| * pname:pViewports is a pointer to an array of slink:VkViewport structures |
| specifying viewport parameters. |
| |
| This command sets the viewport transformation parameters state for |
| subsequent drawing commands |
| ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or] |
| when the graphics pipeline is created with ename:VK_DYNAMIC_STATE_VIEWPORT |
| set in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| Otherwise, this state is specified by the |
| sname:VkPipelineViewportStateCreateInfo::pname:pViewports values used to |
| create the currently active pipeline. |
| |
| The viewport parameters taken from element [eq]#i# of pname:pViewports |
| replace the current state for the viewport index [eq]#pname:firstViewport |
| {plus} i#, for [eq]#i# in [eq]#[0, pname:viewportCount)#. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdSetViewport-firstViewport-01223]] |
| The sum of pname:firstViewport and pname:viewportCount must: be between |
| `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive |
| * [[VUID-vkCmdSetViewport-firstViewport-01224]] |
| If the <<features-multiViewport, pname:multiViewport>> feature is not |
| enabled, pname:firstViewport must: be `0` |
| * [[VUID-vkCmdSetViewport-viewportCount-01225]] |
| If the <<features-multiViewport, pname:multiViewport>> feature is not |
| enabled, pname:viewportCount must: be `1` |
| ifdef::VK_NV_inherited_viewport_scissor[] |
| * [[VUID-vkCmdSetViewport-commandBuffer-04821]] |
| pname:commandBuffer must: not have |
| slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D |
| enabled |
| endif::VK_NV_inherited_viewport_scissor[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetViewport.adoc[] |
| -- |
| |
| Both slink:VkPipelineViewportStateCreateInfo and flink:vkCmdSetViewport use |
| sname:VkViewport to set the viewport transformation parameters. |
| |
| [open,refpage='VkViewport',desc='Structure specifying a viewport',type='structs'] |
| -- |
| The sname:VkViewport structure is defined as: |
| |
| include::{generated}/api/structs/VkViewport.adoc[] |
| |
| * pname:x and pname:y are the viewport's upper left corner [eq]#(x,y)#. |
| * pname:width and pname:height are the viewport's width and height, |
| respectively. |
| * pname:minDepth and pname:maxDepth are the depth range for the viewport. |
| |
| [NOTE] |
| .Note |
| ==== |
| Despite their names, pname:minDepth can: be less than, equal to, or greater |
| than pname:maxDepth. |
| ==== |
| |
| The framebuffer depth coordinate [eq]#pname:z~f~# may: be represented using |
| either a fixed-point or floating-point representation. |
| However, a floating-point representation must: be used if the depth/stencil |
| attachment has a floating-point depth component. |
| If an [eq]#m#-bit fixed-point representation is used, we assume that it |
| represents each value latexmath:[\frac{k}{2^m - 1}], where [eq]#k {elem} { |
| 0, 1, ..., 2^m^-1 }#, as [eq]#k# (e.g. 1.0 is represented in binary as a |
| string of all ones). |
| |
| The viewport parameters shown in the above equations are found from these |
| values as |
| |
| {empty}:: [eq]#o~x~ = pname:x {plus} pname:width / 2# |
| {empty}:: [eq]#o~y~ = pname:y {plus} pname:height / 2# |
| {empty}:: [eq]#o~z~ = pname:minDepth# |
| ifdef::VK_EXT_depth_clip_control[] |
| (or [eq]#(pname:maxDepth + pname:minDepth) / 2# if |
| slink:VkPipelineViewportDepthClipControlCreateInfoEXT::pname:negativeOneToOne |
| is ename:VK_TRUE) |
| endif::VK_EXT_depth_clip_control[] |
| {empty}:: [eq]#p~x~ = pname:width# |
| {empty}:: [eq]#p~y~ = pname:height# |
| {empty}:: [eq]#p~z~ = pname:maxDepth - pname:minDepth# |
| ifdef::VK_EXT_depth_clip_control[] |
| (or [eq]#(pname:maxDepth - pname:minDepth) / 2# if |
| slink:VkPipelineViewportDepthClipControlCreateInfoEXT::pname:negativeOneToOne |
| is ename:VK_TRUE) |
| endif::VK_EXT_depth_clip_control[] |
| |
| ifdef::VK_QCOM_render_pass_transform[] |
| If a render pass transform is enabled, the values [eq]#(p~x~,p~y~)# and |
| [eq]#(o~x~, o~y~)# defining the viewport are transformed as described in |
| <<vertexpostproc-renderpass-transform, render pass transform>> before |
| participating in the viewport transform. |
| endif::VK_QCOM_render_pass_transform[] |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_maintenance1[] |
| The application can: specify a negative term for pname:height, which has the |
| effect of negating the y coordinate in clip space before performing the |
| transform. |
| When using a negative pname:height, the application should: also adjust the |
| pname:y value to point to the lower left corner of the viewport instead of |
| the upper left corner. |
| Using the negative pname:height allows the application to avoid having to |
| negate the y component of the code:Position output from the last |
| <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>>. |
| endif::VK_VERSION_1_1,VK_KHR_maintenance1[] |
| |
| The width and height of the <<limits-maxViewportDimensions, |
| implementation-dependent maximum viewport dimensions>> must: be greater than |
| or equal to the width and height of the largest image which can: be created |
| and attached to a framebuffer. |
| |
| The floating-point viewport bounds are represented with an |
| <<limits-viewportSubPixelBits, implementation-dependent precision>>. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkViewport-width-01770]] |
| pname:width must: be greater than `0.0` |
| * [[VUID-VkViewport-width-01771]] |
| pname:width must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[0] |
| ifndef::VKSC_VERSION_1_0[] |
| * [[VUID-VkViewport-apiVersion-07917]] |
| If the apiext:VK_KHR_maintenance1 extension is not enabled, the |
| apiext:VK_AMD_negative_viewport_height extension is not enabled, and |
| slink:VkPhysicalDeviceProperties::pname:apiVersion is less than Vulkan |
| 1.1, pname:height must: be greater than `0.0` |
| endif::VKSC_VERSION_1_0[] |
| * [[VUID-VkViewport-height-01773]] |
| The absolute value of pname:height must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[1] |
| * [[VUID-VkViewport-x-01774]] |
| pname:x must: be greater than or equal to pname:viewportBoundsRange[0] |
| * [[VUID-VkViewport-x-01232]] |
| [eq]#(pname:x {plus} pname:width)# must: be less than or equal to |
| pname:viewportBoundsRange[1] |
| * [[VUID-VkViewport-y-01775]] |
| pname:y must: be greater than or equal to pname:viewportBoundsRange[0] |
| ifdef::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[] |
| * [[VUID-VkViewport-y-01776]] |
| pname:y must: be less than or equal to pname:viewportBoundsRange[1] |
| * [[VUID-VkViewport-y-01777]] |
| [eq]#(pname:y {plus} pname:height)# must: be greater than or equal to |
| pname:viewportBoundsRange[0] |
| endif::VK_VERSION_1_1,VK_KHR_maintenance1,VK_AMD_negative_viewport_height[] |
| * [[VUID-VkViewport-y-01233]] |
| [eq]#(pname:y {plus} pname:height)# must: be less than or equal to |
| pname:viewportBoundsRange[1] |
| ifdef::VK_EXT_depth_range_unrestricted[] |
| * [[VUID-VkViewport-minDepth-01234]] |
| If the `apiext:VK_EXT_depth_range_unrestricted` extension is not |
| enabled, pname:minDepth must: be between `0.0` and `1.0`, inclusive |
| endif::VK_EXT_depth_range_unrestricted[] |
| ifndef::VK_EXT_depth_range_unrestricted[] |
| * [[VUID-VkViewport-minDepth-02540]] |
| pname:minDepth must: be between `0.0` and `1.0`, inclusive |
| endif::VK_EXT_depth_range_unrestricted[] |
| ifdef::VK_EXT_depth_range_unrestricted[] |
| * [[VUID-VkViewport-maxDepth-01235]] |
| If the `apiext:VK_EXT_depth_range_unrestricted` extension is not |
| enabled, pname:maxDepth must: be between `0.0` and `1.0`, inclusive |
| endif::VK_EXT_depth_range_unrestricted[] |
| ifndef::VK_EXT_depth_range_unrestricted[] |
| * [[VUID-VkViewport-maxDepth-02541]] |
| pname:maxDepth must: be between `0.0` and `1.0`, inclusive |
| endif::VK_EXT_depth_range_unrestricted[] |
| **** |
| |
| include::{generated}/validity/structs/VkViewport.adoc[] |
| -- |