固定功能顶点后处理

光栅化前着色器阶段之后,以下固定功能操作将应用于生成的图元的顶点

接下来,在图元上执行光栅化,如光栅化一章所述。

变换反馈

在任何其他固定功能顶点后处理之前,光栅化前着色器阶段中最后一个着色器的顶点输出可以写入绑定到命令缓冲区的一个或多个变换反馈缓冲区。要捕获顶点输出,最后一个光栅化前着色器阶段着色器必须使用 Xfb 执行模式声明。使用 XfbBuffer 修饰的输出将写入到绑定到命令缓冲区时对应的变换反馈缓冲区。变换反馈缓冲区通过使用vkCmdBindTransformFeedbackBuffersEXT绑定到命令缓冲区。变换反馈通过调用vkCmdBeginTransformFeedbackEXT激活,并通过调用vkCmdEndTransformFeedbackEXT停用。写入顶点数据后,可以使用vkCmdDrawIndirectByteCountEXT启动新的绘制,其中 vertexCount 来自先前变换反馈写入的字节数。

当单个点、线或三角形图元在变换反馈处于活动状态时到达变换反馈阶段时,指定输出变量的值将被组装成图元并附加到绑定的变换反馈缓冲区。激活变换反馈后,第一个组装图元的值将写入绑定变换反馈缓冲区的起始偏移量,后续图元将附加到该缓冲区。如果指定了可选的 pCounterBufferspCounterBufferOffsets 参数,则会调整变换反馈缓冲区内的起始点,以便将数据附加到先前写入的值,该值由实现存储在计数器缓冲区中的值指示。

对于多顶点图元,给定顶点的所有值在写入任何其他顶点的值之前写入。当transformFeedbackPreservesProvokingVertex功能未启用时,实现可以先写入图元内的任何顶点,但是该图元的所有后续顶点必须按照一致的绕序写入,该顺序定义如下

transformFeedbackPreservesProvokingVertex功能启用时,除了以一致的绕序写入顶点外,顶点顺序必须保留每个图元的激发顶点

  • 管线的激发顶点模式VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT 时,图元的激发顶点必须是写入的第一个顶点。

  • 管线的触发顶点模式VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT 时,图元的触发顶点必须是最后写入的顶点。

如果transformFeedbackPreservesTriangleFanProvokingVertexVK_FALSE,并且几何曲面细分着色器均未激活,并且图元拓扑结构VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,那么即使启用了transformFeedbackPreservesProvokingVertex 功能,每个图元写入的第一个顶点也是实现定义的。

当捕获顶点时,与每个变换反馈缓冲区关联的步幅(由 XfbStride 修饰符指示)表示在变换反馈缓冲区中为每个顶点保留的存储字节数。对于捕获的每个顶点,每个带有 Offset 修饰符的输出属性都将被写入到为该顶点保留的存储空间中。当写入数组或结构类型的输出变量时,单个数组元素或结构成员将按顺序紧密打包写入。对于向量类型,单个分量按顺序写入。对于矩阵类型,输出将作为列向量数组写入。

如果具有指定变换反馈偏移量的输出的任何分量没有被其着色器写入,则该分量记录的值是未定义的。输出变量的所有分量必须以对齐到分量大小的偏移量写入。输出变量的每个分量的大小必须至少为 32 位。当捕获顶点时,保留的存储空间中任何未与具有指定变换反馈偏移量的输出变量关联的部分都将保持不变。

当变换反馈处于非活动状态时,不记录任何顶点。如果 pCounterBufferspCounterBufferOffsets 数组中存在有效的计数器缓冲区句柄和计数器缓冲区偏移量,则对相应变换反馈缓冲区的写入将从计数器缓冲区位置中存储的值表示的字节偏移量开始。

条带或扇形图元的各个线或三角形将被提取并单独记录。不完整的图元不会被记录。

当使用几何着色器将顶点发射到多个顶点流时,当输出图元类型有足够的顶点发射时,将为每个流组装并输出图元。分配给给定变换反馈缓冲区的所有输出都必须来自单个顶点流。

变换反馈缓冲区的大小由 vkCmdBindTransformFeedbackBuffersEXTpSizes 参数为每个绑定的缓冲区定义,或由绑定缓冲区的大小定义,以较小者为准。如果任何变换反馈缓冲区中剩余的空间小于基于该 XfbBufferXfbStride 计算的该图元的所有顶点数据的大小,则该图元的任何顶点数据都不会记录在任何变换反馈缓冲区中,并且在所有变换反馈缓冲区对应的 VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT 查询中写入的图元数量的值不再递增。

任何对未绑定到变换反馈缓冲区的 XfbBuffer 的输出都将被忽略。

要将变换反馈缓冲区绑定到命令缓冲区以在后续绘图命令中使用,请调用

// Provided by VK_EXT_transform_feedback
void vkCmdBindTransformFeedbackBuffersEXT(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstBinding,
    uint32_t                                    bindingCount,
    const VkBuffer*                             pBuffers,
    const VkDeviceSize*                         pOffsets,
    const VkDeviceSize*                         pSizes);
  • commandBuffer 是将命令记录到的命令缓冲区。

  • firstBinding 是第一个变换反馈绑定的索引,该绑定的状态由命令更新。

  • bindingCount 是要更新状态的变换反馈绑定的数量。

  • pBuffers 是指向缓冲区句柄数组的指针。

  • pOffsets 是指向缓冲区偏移量数组的指针。

  • pSizesNULL 或指向 VkDeviceSize 缓冲区大小数组的指针,指定要捕获到相应变换反馈缓冲区的最大字节数。如果 pSizesNULL,或者 pSizes 数组元素的值为 VK_WHOLE_SIZE,则捕获的最大字节数将是相应缓冲区的大小减去缓冲区偏移量。

pBufferspOffsetspSizes 的元素 i 获取的值将替换变换反馈绑定 firstBinding + i 的当前状态,其中 i[0, bindingCount) 范围内。变换反馈绑定将更新为从缓冲区 pBuffers[i] 的起始位置开始,偏移量由 pOffsets[i] 指示。

有效用法
  • VUID-vkCmdBindTransformFeedbackBuffersEXT-transformFeedback-02355
    必须启用 VkPhysicalDeviceTransformFeedbackFeaturesEXT::transformFeedback

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02356
    firstBinding 必须小于 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackBuffers

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357
    firstBindingbindingCount 的总和必须小于或等于 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackBuffers

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02358
    pOffsets 的所有元素必须小于 pBuffers 中相应元素的大小

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02359
    pOffsets 的所有元素必须是 4 的倍数

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02360
    pBuffers 的所有元素必须已使用 VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT 标志创建

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-pSize-02361
    如果指定了可选的 pSize 数组,则 pSizes 的每个元素必须VK_WHOLE_SIZE,或者小于或等于 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackBufferSize

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-pSizes-02362
    pSizes 的所有元素必须VK_WHOLE_SIZE,或者小于或等于 pBuffers 中对应缓冲区的大小

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363
    所有 pOffsets 的元素加上 pSizes 的元素,其中 pSizes 的元素不是 VK_WHOLE_SIZE必须 小于或等于 pBuffers 中对应缓冲区的大小。

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02364
    pBuffers 中每个非稀疏的元素必须完全且连续地绑定到单个 VkDeviceMemory 对象。

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-None-02365
    当记录 vkCmdBindTransformFeedbackBuffersEXT 命令时,转换反馈必须未激活。

有效使用(隐式)
  • VUID-vkCmdBindTransformFeedbackBuffersEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-parameter
    pBuffers 必须是指向 bindingCount 个有效 VkBuffer 句柄数组的有效指针。

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-parameter
    pOffsets 必须是指向 bindingCountVkDeviceSize 值数组的有效指针。

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-bindingCount-arraylength
    bindingCount 必须大于 0

  • VUID-vkCmdBindTransformFeedbackBuffersEXT-commonparent
    commandBufferpBuffers 的元素必须从同一个 VkDevice 创建、分配或检索。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

通过调用以下命令,激活特定转换反馈缓冲区的转换反馈:

// Provided by VK_EXT_transform_feedback
void vkCmdBeginTransformFeedbackEXT(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstCounterBuffer,
    uint32_t                                    counterBufferCount,
    const VkBuffer*                             pCounterBuffers,
    const VkDeviceSize*                         pCounterBufferOffsets);
  • commandBuffer 是将命令记录到的命令缓冲区。

  • firstCounterBuffer 是对应于 pCounterBuffers[0] 和 pCounterBufferOffsets[0] 的第一个转换反馈缓冲区的索引。

  • counterBufferCountpCounterBufferspCounterBufferOffsets 数组的大小。

  • pCounterBuffersNULL 或指向计数器缓冲区的 VkBuffer 句柄数组的指针。每个缓冲区都包含一个 4 字节的整数值,表示从相应的转换反馈缓冲区的起始位置开始捕获顶点数据的字节偏移量。如果存储到计数器缓冲区位置的字节偏移量是使用 vkCmdEndTransformFeedbackEXT 完成的,则可以用于从先前的位置恢复转换反馈。如果 pCounterBuffersNULL,则转换反馈将开始在所有绑定的转换反馈缓冲区中捕获到字节偏移量为零的顶点数据。对于 pCounterBuffers 的每个 VK_NULL_HANDLE 元素,转换反馈将开始在相应的绑定转换反馈缓冲区中捕获到字节零的顶点数据。

  • pCounterBufferOffsetsNULL 或指向 VkDeviceSize 值数组的指针,该数组指定每个 pCounterBuffers 内的偏移量,其中先前写入了计数器值。这些偏移量处每个计数器缓冲区中的位置必须足够大,以包含 4 个字节的数据。此数据是先前转换反馈捕获到此缓冲区的字节数。如果 pCounterBufferOffsetsNULL,则假定偏移量为零。

活动的转换反馈缓冲区将捕获从绑定图形管道中相应的 XfbBuffer 发出的图元。任何未输出到活动转换反馈缓冲区的 XfbBuffer 都不会被捕获。

有效用法
  • VUID-vkCmdBeginTransformFeedbackEXT-transformFeedback-02366
    必须启用 VkPhysicalDeviceTransformFeedbackFeaturesEXT::transformFeedback

  • VUID-vkCmdBeginTransformFeedbackEXT-None-02367
    转换反馈必须未激活。

  • VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02368
    firstCounterBuffer 必须小于 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackBuffers

  • VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369
    firstCounterBuffercounterBufferCount 的总和必须小于或等于 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackBuffers

  • VUID-vkCmdBeginTransformFeedbackEXT-counterBufferCount-02607
    如果 counterBufferCount 不为 0pCounterBuffers 不为 NULL,则 pCounterBuffers 必须是指向 counterBufferCountVkBuffer 句柄的有效指针,这些句柄要么有效,要么为 VK_NULL_HANDLE

  • VUID-vkCmdBeginTransformFeedbackEXT-pCounterBufferOffsets-02370
    对于数组中的每个缓冲区句柄,如果它不是 VK_NULL_HANDLE,则必须引用一个足够大的缓冲区,以便在 pCounterBufferOffsets 数组中相应的偏移量处容纳 4 个字节。

  • VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffer-02371
    如果 pCounterBufferNULL,则 pCounterBufferOffsets 必须也为 NULL

  • VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffers-02372
    对于 pCounterBuffers 数组中不是 VK_NULL_HANDLE 的每个缓冲区句柄,它必须已使用包含 VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXTusage 值创建。

  • VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-09630
    firstCounterBuffercounterBufferCount 的总和必须小于或等于由 vkCmdBindTransformFeedbackBuffersEXT 绑定的转换反馈缓冲区的数量。

  • VUID-vkCmdBeginTransformFeedbackEXT-None-06233
    如果未启用 shaderObject 功能,则必须将有效的图形管线绑定到 VK_PIPELINE_BIND_POINT_GRAPHICS

  • VUID-vkCmdBeginTransformFeedbackEXT-None-04128
    绑定图形管线的最后一个光栅化前着色器阶段必须已使用 Xfb 执行模式声明。

  • VUID-vkCmdBeginTransformFeedbackEXT-None-02373
    在启用多视图的渲染通道实例中,不得激活转换反馈。

有效使用(隐式)
  • VUID-vkCmdBeginTransformFeedbackEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdBeginTransformFeedbackEXT-pCounterBufferOffsets-parameter
    如果 counterBufferCount 不为 0,并且 pCounterBufferOffsets 不为 NULL,则 pCounterBufferOffsets 必须是指向 counterBufferCountVkDeviceSize 值的有效指针。

  • VUID-vkCmdBeginTransformFeedbackEXT-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdBeginTransformFeedbackEXT-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdBeginTransformFeedbackEXT-renderpass
    此命令必须仅在渲染通道实例内部调用。

  • VUID-vkCmdBeginTransformFeedbackEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

  • VUID-vkCmdBeginTransformFeedbackEXT-commonparent
    commandBufferpCounterBuffers 中作为非忽略参数的有效句柄的元素必须已从同一个 VkDevice 创建、分配或检索。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

内部

外部

图形

状态

通过调用以下命令,使特定转换反馈缓冲区的转换反馈变为非活动状态

// Provided by VK_EXT_transform_feedback
void vkCmdEndTransformFeedbackEXT(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstCounterBuffer,
    uint32_t                                    counterBufferCount,
    const VkBuffer*                             pCounterBuffers,
    const VkDeviceSize*                         pCounterBufferOffsets);
  • commandBuffer 是将命令记录到的命令缓冲区。

  • firstCounterBuffer 是对应于 pCounterBuffers[0] 和 pCounterBufferOffsets[0] 的第一个转换反馈缓冲区的索引。

  • counterBufferCountpCounterBufferspCounterBufferOffsets 数组的大小。

  • pCounterBuffersNULL 或指向计数器缓冲区的 VkBuffer 句柄数组的指针。计数器缓冲区用于记录每个转换反馈缓冲区的当前字节位置,其中将捕获下一个顶点输出数据。后续的 vkCmdBeginTransformFeedbackEXT 调用可以使用此信息来从该位置恢复转换反馈捕获。 vkCmdDrawIndirectByteCountEXT 也可以使用它来确定绘制调用的顶点计数。

  • pCounterBufferOffsetsNULL 或指向 VkDeviceSize 值数组的指针,指定 pCounterBuffers 中每个计数器缓冲区内可以写入计数值的偏移量。这些偏移量处每个计数器缓冲区中的位置必须足够大,能够容纳 4 个字节的数据。存储在此位置的数据是从转换反馈缓冲区绑定的起始位置开始的字节偏移量,其中将写入下一个顶点数据。如果 pCounterBufferOffsetsNULL,则假定偏移量为零。

有效用法
  • VUID-vkCmdEndTransformFeedbackEXT-transformFeedback-02374
    必须启用 VkPhysicalDeviceTransformFeedbackFeaturesEXT::transformFeedback

  • VUID-vkCmdEndTransformFeedbackEXT-None-02375
    转换反馈必须处于活动状态。

  • VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02376
    firstCounterBuffer 必须小于 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackBuffers

  • VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377
    firstCounterBuffercounterBufferCount 的总和必须小于或等于 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackBuffers

  • VUID-vkCmdEndTransformFeedbackEXT-counterBufferCount-02608
    如果 counterBufferCount 不为 0pCounterBuffers 不为 NULL,则 pCounterBuffers 必须是指向 counterBufferCountVkBuffer 句柄的有效指针,这些句柄要么有效,要么为 VK_NULL_HANDLE

  • VUID-vkCmdEndTransformFeedbackEXT-pCounterBufferOffsets-02378
    对于数组中的每个缓冲区句柄,如果它不是 VK_NULL_HANDLE,则必须引用一个足够大的缓冲区,以便在 pCounterBufferOffsets 数组中相应的偏移量处容纳 4 个字节。

  • VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffer-02379
    如果 pCounterBufferNULL,则 pCounterBufferOffsets 必须也为 NULL

  • VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffers-02380
    对于 pCounterBuffers 数组中不是 VK_NULL_HANDLE 的每个缓冲区句柄,它必须已使用包含 VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXTusage 值创建。

有效使用(隐式)
  • VUID-vkCmdEndTransformFeedbackEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdEndTransformFeedbackEXT-pCounterBufferOffsets-parameter
    如果 counterBufferCount 不为 0,并且 pCounterBufferOffsets 不为 NULL,则 pCounterBufferOffsets 必须是指向 counterBufferCountVkDeviceSize 值的有效指针。

  • VUID-vkCmdEndTransformFeedbackEXT-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdEndTransformFeedbackEXT-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdEndTransformFeedbackEXT-renderpass
    此命令必须仅在渲染通道实例内部调用。

  • VUID-vkCmdEndTransformFeedbackEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

  • VUID-vkCmdEndTransformFeedbackEXT-commonparent
    commandBufferpCounterBuffers 中作为非忽略参数的有效句柄的元素必须已从同一个 VkDevice 创建、分配或检索。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

内部

外部

图形

状态

视口混合

发送到给定视口的每个图元都会在其裁剪坐标上应用混合和可选的求反。应用的混合取决于视口索引,并由 VkPipelineViewportSwizzleStateCreateInfoNV 管线状态控制。

// Provided by VK_NV_viewport_swizzle
typedef struct VkPipelineViewportSwizzleStateCreateInfoNV {
    VkStructureType                                sType;
    const void*                                    pNext;
    VkPipelineViewportSwizzleStateCreateFlagsNV    flags;
    uint32_t                                       viewportCount;
    const VkViewportSwizzleNV*                     pViewportSwizzles;
} VkPipelineViewportSwizzleStateCreateInfoNV;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • flags 保留供将来使用。

  • viewportCount 是管线使用的视口混合的数量。

  • pViewportSwizzles 是指向 VkViewportSwizzleNV 结构体数组的指针,定义了视口混合(swizzle)。

有效用法
  • VUID-VkPipelineViewportSwizzleStateCreateInfoNV-viewportCount-01215
    viewportCount 必须大于或等于 VkPipelineViewportStateCreateInfo 中设置的 viewportCount

有效使用(隐式)
  • VUID-VkPipelineViewportSwizzleStateCreateInfoNV-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV

  • VUID-VkPipelineViewportSwizzleStateCreateInfoNV-flags-zerobitmask
    flags 必须0

  • VUID-VkPipelineViewportSwizzleStateCreateInfoNV-pViewportSwizzles-parameter
    pViewportSwizzles 必须是指向 viewportCount 个有效 VkViewportSwizzleNV 结构体数组的有效指针。

  • VUID-VkPipelineViewportSwizzleStateCreateInfoNV-viewportCount-arraylength
    viewportCount 必须大于 0

// Provided by VK_NV_viewport_swizzle
typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV;

VkPipelineViewportSwizzleStateCreateFlagsNV 是用于设置掩码的位掩码类型,但目前保留供将来使用。

VkPipelineViewportSwizzleStateCreateInfoNV 状态通过将此结构体添加到 VkPipelineViewportStateCreateInfo 结构体的 pNext 链,并使用 vkCreateGraphicsPipelines 设置图形管线状态来设置。

动态设置视口混合状态,请调用

// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_viewport_swizzle, VK_EXT_shader_object with VK_NV_viewport_swizzle
void vkCmdSetViewportSwizzleNV(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstViewport,
    uint32_t                                    viewportCount,
    const VkViewportSwizzleNV*                  pViewportSwizzles);
  • commandBuffer 是将记录命令的命令缓冲区。

  • firstViewport 是由命令更新其参数的第一个视口的索引。

  • viewportCount 是由命令更新其参数的视口数量。

  • pViewportSwizzles 是一个指向 VkViewportSwizzleNV 结构体数组的指针,指定视口混合。

当使用着色器对象进行绘制时,或者当图形管线创建时,在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV,此命令为后续绘制命令设置视口混合状态。否则,此状态由用于创建当前活动管线的 VkPipelineViewportSwizzleStateCreateInfoNV::viewportCountVkPipelineViewportSwizzleStateCreateInfoNV::pViewportSwizzles 值指定。

有效用法
有效使用(隐式)
  • VUID-vkCmdSetViewportSwizzleNV-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetViewportSwizzleNV-pViewportSwizzles-parameter
    pViewportSwizzles 必须是指向 viewportCount 个有效 VkViewportSwizzleNV 结构体数组的有效指针。

  • VUID-vkCmdSetViewportSwizzleNV-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdSetViewportSwizzleNV-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetViewportSwizzleNV-videocoding
    此命令必须仅在视频编码范围之外调用。

  • VUID-vkCmdSetViewportSwizzleNV-viewportCount-arraylength
    viewportCount 必须大于 0

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

从 0 到 viewportCount - 1 指定的每个视口的 x、y、z、w 混合状态被设置为 VkViewportSwizzleNV 结构体中对应的 xyzw。每个分量都是 VkViewportCoordinateSwizzleNV 类型,它决定了该分量的混合类型。x 的值计算位置的新 x 分量为:

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;

yzw 坐标执行类似的选取。此混合在裁剪和透视除法之前应用。如果未指定活动视口索引的混合,则 x 的混合为 VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NVyVK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NVzVK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV,而 wVK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV

视口混合参数通过将 VkGraphicsPipelineCreateInfopNext 指针设置为指向 VkPipelineViewportSwizzleStateCreateInfoNV 结构体来指定。VkPipelineViewportSwizzleStateCreateInfoNV 使用 VkViewportSwizzleNV 来设置视口混合参数。

VkViewportSwizzleNV 结构体定义如下:

// Provided by VK_NV_viewport_swizzle
typedef struct VkViewportSwizzleNV {
    VkViewportCoordinateSwizzleNV    x;
    VkViewportCoordinateSwizzleNV    y;
    VkViewportCoordinateSwizzleNV    z;
    VkViewportCoordinateSwizzleNV    w;
} VkViewportSwizzleNV;
有效使用(隐式)

VkViewportSwizzleNV::xyzw 成员的可能值,指定图元相应分量的混合如下:

// Provided by VK_NV_viewport_swizzle
typedef enum VkViewportCoordinateSwizzleNV {
    VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV = 0,
    VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV = 1,
    VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV = 2,
    VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV = 3,
    VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV = 4,
    VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV = 5,
    VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV = 6,
    VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV = 7,
} VkViewportCoordinateSwizzleNV;

这些值在视口混合中详细描述。

平面着色

平面着色一个顶点输出属性意味着将图元的所有顶点分配给该输出的相同值。分配的输出值是图元的引发顶点的值。平面着色应用于那些与被装饰为 Flat 的片段输入属性匹配的顶点属性。

如果网格着色(mesh)、几何着色(geometry)或曲面细分着色(tessellation shading)均未激活,则触发顶点由执行绘制命令时使用的、由VkPipelineInputAssemblyStateCreateInfo定义的图元拓扑结构topology确定。

如果激活了使用 MeshNV Execution Model 的着色器,则触发顶点由OutputPointsOutputLinesNVOutputTrianglesNV执行模式定义的图元拓扑结构确定。

如果激活了使用 MeshEXT Execution Model 的着色器,则触发顶点由OutputPointsOutputLinesEXTOutputTrianglesEXT执行模式定义的图元拓扑结构确定。

如果几何着色处于激活状态,则触发顶点由OutputPointsOutputLineStripOutputTriangleStrip执行模式定义的图元拓扑结构确定。

如果曲面细分着色处于激活状态但几何着色未激活,则触发顶点可以是每个图元中的任何顶点。

对于给定的图元拓扑结构,管线的触发顶点模式决定哪个顶点是触发顶点。要指定触发顶点模式,请在创建管线时,将 VkPipelineRasterizationProvokingVertexStateCreateInfoEXT 结构体包含在VkPipelineRasterizationStateCreateInfo::pNext 链中。

VkPipelineRasterizationProvokingVertexStateCreateInfoEXT 结构体的定义如下:

// Provided by VK_EXT_provoking_vertex
typedef struct VkPipelineRasterizationProvokingVertexStateCreateInfoEXT {
    VkStructureType             sType;
    const void*                 pNext;
    VkProvokingVertexModeEXT    provokingVertexMode;
} VkPipelineRasterizationProvokingVertexStateCreateInfoEXT;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • provokingVertexMode 是一个 VkProvokingVertexModeEXT 值,用于选择触发顶点模式。

如果在创建管线时未提供此结构体,则管线将使用 VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT 模式。

如果 provokingVertexModePerPipeline 限制为 VK_FALSE,则渲染过程实例中绑定的所有管线必须具有相同的 provokingVertexMode

有效用法
  • VUID-VkPipelineRasterizationProvokingVertexStateCreateInfoEXT-provokingVertexMode-04883
    如果 provokingVertexModeVK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT,则必须启用provokingVertexLast 功能。

有效使用(隐式)
  • VUID-VkPipelineRasterizationProvokingVertexStateCreateInfoEXT-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT

  • VUID-VkPipelineRasterizationProvokingVertexStateCreateInfoEXT-provokingVertexMode-parameter
    provokingVertexMode 必须是有效的 VkProvokingVertexModeEXT 值。

VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::provokingVertexMode 的可能值如下:

// Provided by VK_EXT_provoking_vertex
typedef enum VkProvokingVertexModeEXT {
    VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT = 0,
    VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT = 1,
} VkProvokingVertexModeEXT;
  • VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT 指定触发顶点是图元使用的顶点列表中第一个非邻接顶点。

  • VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT 指定触发顶点是图元使用的顶点列表中最后一个非邻接顶点。

这些模式在图元拓扑结构中进行了更精确的描述。

动态设置 provokingVertexMode 状态,请调用:

// Provided by VK_EXT_extended_dynamic_state3 with VK_EXT_provoking_vertex, VK_EXT_provoking_vertex with VK_EXT_shader_object
void vkCmdSetProvokingVertexModeEXT(
    VkCommandBuffer                             commandBuffer,
    VkProvokingVertexModeEXT                    provokingVertexMode);
  • commandBuffer 是将记录命令的命令缓冲区。

  • provokingVertexMode 指定 provokingVertexMode 状态。

当使用着色器对象进行绘制,或者在VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT 的情况下创建图形管线时,此命令为后续绘制命令设置 provokingVertexMode 状态。否则,此状态由用于创建当前活动管线的 VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::provokingVertexMode 值指定。

有效用法
  • VUID-vkCmdSetProvokingVertexModeEXT-None-09423
    以下条件中,至少有一个必须为真:

  • VUID-vkCmdSetProvokingVertexModeEXT-provokingVertexMode-07447
    如果 provokingVertexModeVK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT,则必须启用provokingVertexLast 功能。

有效使用(隐式)
  • VUID-vkCmdSetProvokingVertexModeEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetProvokingVertexModeEXT-provokingVertexMode-parameter
    provokingVertexMode 必须是有效的 VkProvokingVertexModeEXT 值。

  • VUID-vkCmdSetProvokingVertexModeEXT-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdSetProvokingVertexModeEXT-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetProvokingVertexModeEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

图元裁剪

图元会根据剔除体进行剔除,然后被裁剪到裁剪体。在裁剪坐标中,视见体定义为:

其中,如果 VkPipelineViewportDepthClipControlCreateInfoEXT::negativeOneToOneVK_TRUE,则 zm 等于 -wc,否则 zm 等于零。

此视见体可以受到最多 VkPhysicalDeviceLimits::maxClipDistances 个应用程序定义的半空间的进一步限制。

剔除体是最多 VkPhysicalDeviceLimits::maxCullDistances 个应用程序定义的半空间的交集(如果未启用任何应用程序定义的剔除半空间,则会跳过针对剔除体的剔除)。

着色器必须为每个启用的剔除半空间向 CullDistance 数组的元素写入单个剔除距离。如果对于正在考虑的图元的所有顶点,任何启用剔除半空间的剔除距离为负,则该图元将被丢弃。否则,该图元将按照如下定义被裁剪到裁剪体。

裁剪体是最多 VkPhysicalDeviceLimits::maxClipDistances 个应用程序定义的半空间与视见体的交集(如果未启用任何应用程序定义的裁剪半空间,则裁剪体为视见体)。

着色器必须为每个启用的裁剪半空间向 ClipDistance 数组的元素写入单个裁剪距离。裁剪半空间 i 由满足以下不等式的点集给出:

ci(P) ≥ 0

其中 ci(P) 是点 P 处的裁剪距离 i。对于点图元,ci(P) 只是相关顶点的裁剪距离。对于线和三角形图元,每个顶点的裁剪距离使用加权平均值进行插值,权重根据 基本线段光栅化基本多边形光栅化 部分中描述的算法得出,并使用透视插值方程。

启用的应用程序定义的裁剪和剔除半空间的数量分别由内置数组 ClipDistanceCullDistance 的显式大小决定,这两个数组在裁剪之前的最终着色器阶段的入口点的接口中声明为输出。

如果图形管线状态中存在 VkPipelineRasterizationDepthClipStateCreateInfoEXT,则当 VkPipelineRasterizationDepthClipStateCreateInfoEXT::depthClipEnableVK_FALSE 时,深度裁剪将被禁用。否则,如果不存在 VkPipelineRasterizationDepthClipStateCreateInfoEXT,则当 VkPipelineRasterizationStateCreateInfo::depthClampEnableVK_TRUE 时,深度裁剪将被禁用。

动态设置启用或禁用深度钳位,请调用

// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetDepthClampEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    depthClampEnable);
  • commandBuffer 是将记录命令的命令缓冲区。

  • depthClampEnable 指定是否启用深度钳位。

当使用着色器对象进行绘制时,或者当使用在VkPipelineDynamicStateCreateInfo::pDynamicStates中设置的 VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT创建图形管线时,此命令设置后续绘制命令是否启用或禁用深度钳位。否则,此状态由用于创建当前活动管线的VkPipelineRasterizationStateCreateInfo::depthClampEnable值指定。

如果动态更改深度钳位状态,并且创建管线时未启用 VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT,则当禁用深度钳位时启用深度裁剪,反之亦然。

有效用法
  • VUID-vkCmdSetDepthClampEnableEXT-None-09423
    以下条件中,至少有一个必须为真:

  • VUID-vkCmdSetDepthClampEnableEXT-depthClamp-07449
    如果未启用 depthClamp 功能,则 depthClampEnable **必须**为 VK_FALSE

有效使用(隐式)
  • VUID-vkCmdSetDepthClampEnableEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetDepthClampEnableEXT-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdSetDepthClampEnableEXT-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetDepthClampEnableEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

动态设置启用或禁用深度裁剪,请调用

// Provided by VK_EXT_depth_clip_enable with VK_EXT_extended_dynamic_state3, VK_EXT_depth_clip_enable with VK_EXT_shader_object
void vkCmdSetDepthClipEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    depthClipEnable);
  • commandBuffer 是将记录命令的命令缓冲区。

  • depthClipEnable 指定是否启用深度裁剪。

当使用着色器对象进行绘制时,或者当使用在VkPipelineDynamicStateCreateInfo::pDynamicStates中设置的 VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT创建图形管线时,此命令设置后续绘制命令是否启用或禁用深度裁剪。否则,此状态由用于创建当前活动管线的VkPipelineRasterizationDepthClipStateCreateInfoEXT::depthClipEnable值指定,如果未指定 VkPipelineRasterizationDepthClipStateCreateInfoEXT,则由 VkPipelineRasterizationStateCreateInfo::depthClampEnable 的反向值指定。

有效用法
有效使用(隐式)
  • VUID-vkCmdSetDepthClipEnableEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetDepthClipEnableEXT-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdSetDepthClipEnableEXT-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetDepthClipEnableEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

当禁用深度裁剪时,平面方程

zm ≤ zc ≤ wc

(请参阅上面的裁剪体定义)被视图体裁剪忽略(实际上,没有近平面或远平面裁剪)。

如果正在考虑的图元是点或线段,则如果其顶点完全位于裁剪体内部,则裁剪将保持不变。

VkPhysicalDevicePointClippingProperties::pointClippingBehavior 的可能值,指定顶点位于裁剪体外部的点图元的裁剪行为如下:

// Provided by VK_VERSION_1_1
typedef enum VkPointClippingBehavior {
    VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES = 0,
    VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1,
  // Provided by VK_KHR_maintenance2
    VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES,
  // Provided by VK_KHR_maintenance2
    VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY,
} VkPointClippingBehavior;

或等效的

// Provided by VK_KHR_maintenance2
typedef VkPointClippingBehavior VkPointClippingBehaviorKHR;
  • VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES 指定如果顶点位于任何裁剪平面(包括边界视图体的平面)之外,则丢弃该图元。

  • VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY 指定仅当顶点位于任何用户裁剪平面之外时才丢弃该图元。

如果线段的任何一个顶点位于裁剪体之外,则 **可以** 裁剪该线段,并为位于裁剪体外部的每个顶点计算新的顶点坐标。裁剪的线段端点位于原始线段和裁剪体的边界上。

此裁剪为每个裁剪的顶点生成一个值 0 ≤ t ≤ 1。如果裁剪顶点的坐标为 P,而未裁剪的线段的顶点坐标为 P1P2,则 t 满足以下方程

P = t P1 + (1-t) P2.

t 用于裁剪顶点输出属性,如 裁剪着色器输出 中所述。

如果图元是多边形,如果其每个边都完全位于裁剪体内部,则该多边形将保持不变,否则将被裁剪或丢弃。如果多边形的边与裁剪体边界相交,则相交的边将通过位于裁剪体边界上的新边重新连接 - 在某些情况下需要将新顶点引入多边形中。

如果多边形与裁剪体边界的边相交,则裁剪后的多边形 **必须** 包括此边界边上的一个点。

使用应用程序定义的半空间渲染的图元必须满足互补性准则。假设绘制一系列图元,其中每个顶点 i 都有一个指定的裁剪距离 di (如果启用了多个半空间,则可能有多个类似指定的裁剪距离)。接下来,假设再次绘制相同的图元系列,但将每个此类裁剪距离替换为 -di (并且图形管线的其余部分保持不变)。在这种情况下,图元不能遗漏任何像素,并且在被裁剪平面切割的区域中,像素不能被绘制两次。

VkPipelineViewportDepthClipControlCreateInfoEXT 结构定义如下:

// Provided by VK_EXT_depth_clip_control
typedef struct VkPipelineViewportDepthClipControlCreateInfoEXT {
    VkStructureType    sType;
    const void*        pNext;
    VkBool32           negativeOneToOne;
} VkPipelineViewportDepthClipControlCreateInfoEXT;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • negativeOneToOne视图体中的 zm 设置为 -wc

有效用法
  • VUID-VkPipelineViewportDepthClipControlCreateInfoEXT-negativeOneToOne-06470
    如果未启用 depthClipControl 功能,则 negativeOneToOne 必须VK_FALSE

有效使用(隐式)
  • VUID-VkPipelineViewportDepthClipControlCreateInfoEXT-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT

动态设置 negativeOneToOne,请调用:

// Provided by VK_EXT_depth_clip_control with VK_EXT_extended_dynamic_state3, VK_EXT_depth_clip_control with VK_EXT_shader_object
void vkCmdSetDepthClipNegativeOneToOneEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    negativeOneToOne);
  • commandBuffer 是将记录命令的命令缓冲区。

  • negativeOneToOne 指定 negativeOneToOne 状态。

当使用 着色器对象 进行绘制,或者在创建图形管线时,在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT 时,此命令会为后续绘制命令设置 negativeOneToOne 状态。否则,此状态由用于创建当前活动管线的 VkPipelineViewportDepthClipControlCreateInfoEXT::negativeOneToOne 值指定。

有效用法
有效使用(隐式)
  • VUID-vkCmdSetDepthClipNegativeOneToOneEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetDepthClipNegativeOneToOneEXT-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdSetDepthClipNegativeOneToOneEXT-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetDepthClipNegativeOneToOneEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

裁剪着色器输出

接下来,裁剪顶点输出属性。与位于裁剪体内的顶点关联的输出值不受裁剪的影响。但是,如果裁剪了图元,则分配给由裁剪产生的顶点的输出值也将被裁剪。

假设未裁剪的边的两个顶点 P1P2 的输出值分别为 c1c2。对于裁剪点 Pt 的值(请参阅图元裁剪)用于获得与 P 关联的输出值,如下所示:

c = t c1 + (1-t) c2.

(将输出值乘以标量意味着将 xyzw 的每个分量都乘以该标量。)

由于此计算是在除以 wc 之前在裁剪空间中执行的,因此裁剪的输出值是透视正确的。

多边形裁剪会在裁剪体的边界边缘创建一个裁剪的顶点。通过注意多边形裁剪每次都针对一个半空间进行裁剪来处理这种情况。输出值裁剪也以相同的方式完成,以便裁剪点始终出现在多边形边缘(可能已裁剪)与裁剪体边界的交点处。

对于其匹配的片段输入属性使用 NoPerspective 修饰的顶点输出属性,用于获得与 P 关联的输出值的 t 值将进行调整,以产生在帧缓冲区空间中线性变化的结果。

整数或无符号整数类型的输出属性必须始终使用平面着色。平面着色属性在被光栅化的图元上是恒定的(请参阅 基本线段光栅化基本多边形光栅化),并且不执行插值。输出值 c 取自 c1c2,因为已经进行了平面着色,并且这两个值是相同的。

控制视口 W 缩放

如果启用了视口 W 缩放,则剪辑坐标的 W 分量将按照以下方式,由相应视口提供的系数进行修改。

wc' = xcoeff xc + ycoeff yc + wc

VkPipelineViewportWScalingStateCreateInfoNV 结构定义如下:

// Provided by VK_NV_clip_space_w_scaling
typedef struct VkPipelineViewportWScalingStateCreateInfoNV {
    VkStructureType                sType;
    const void*                    pNext;
    VkBool32                       viewportWScalingEnable;
    uint32_t                       viewportCount;
    const VkViewportWScalingNV*    pViewportWScalings;
} VkPipelineViewportWScalingStateCreateInfoNV;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • viewportWScalingEnable 控制是否启用视口 W 缩放。

  • viewportCountW 缩放使用的视口数量,如果启用了视口 W 缩放,则必须与管线中的视口数量匹配。

  • pViewportWScalings 是指向 VkViewportWScalingNV 结构数组的指针,这些结构定义了相应视口的 W 缩放参数。如果视口 W 缩放状态是动态的,则忽略此成员。

有效使用(隐式)
  • VUID-VkPipelineViewportWScalingStateCreateInfoNV-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV

  • VUID-VkPipelineViewportWScalingStateCreateInfoNV-viewportCount-arraylength
    viewportCount 必须大于 0

VkPipelineViewportWScalingStateCreateInfoNV 状态通过将此结构添加到 VkPipelineViewportStateCreateInfo 结构的 pNext 链中,并使用 vkCreateGraphicsPipelines 设置图形管线状态来设置。

动态设置 viewportWScalingEnable 状态,请调用

// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_clip_space_w_scaling, VK_EXT_shader_object with VK_NV_clip_space_w_scaling
void vkCmdSetViewportWScalingEnableNV(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    viewportWScalingEnable);
  • commandBuffer 是将记录命令的命令缓冲区。

  • viewportWScalingEnable 指定 viewportWScalingEnable 状态。

当使用 着色器对象 绘图,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV 时创建时,此命令为后续的绘制命令设置 viewportWScalingEnable 状态。否则,此状态由用于创建当前活动管线的 VkPipelineViewportWScalingStateCreateInfoNV::viewportWScalingEnable 值指定。

有效用法
有效使用(隐式)
  • VUID-vkCmdSetViewportWScalingEnableNV-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetViewportWScalingEnableNV-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdSetViewportWScalingEnableNV-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetViewportWScalingEnableNV-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

动态设置视口 W 缩放参数,请调用

// Provided by VK_NV_clip_space_w_scaling
void vkCmdSetViewportWScalingNV(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstViewport,
    uint32_t                                    viewportCount,
    const VkViewportWScalingNV*                 pViewportWScalings);
  • commandBuffer 是将记录命令的命令缓冲区。

  • firstViewport 是由命令更新其参数的第一个视口的索引。

  • viewportCount 是由命令更新其参数的视口数量。

  • pViewportWScalings 是指向 VkViewportWScalingNV 结构数组的指针,用于指定视口参数。

pViewportWScalings 的元素 i 中获取的视口参数将替换视口索引为 firstViewport + i 的当前状态,其中 i[0, viewportCount) 范围内。

当使用 着色器对象 绘图,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV 时创建时,此命令为后续的绘制命令设置视口 W 缩放。否则,此状态由用于创建当前活动管线的 VkPipelineViewportWScalingStateCreateInfoNV::pViewportWScalings 值指定。

有效用法
  • VUID-vkCmdSetViewportWScalingNV-firstViewport-01324
    firstViewportviewportCount 的总和 必须1VkPhysicalDeviceLimits::maxViewports 之间(包含两者)

有效使用(隐式)
  • VUID-vkCmdSetViewportWScalingNV-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetViewportWScalingNV-pViewportWScalings-parameter
    pViewportWScalings 必须 是指向包含 viewportCountVkViewportWScalingNV 结构的数组的有效指针

  • VUID-vkCmdSetViewportWScalingNV-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdSetViewportWScalingNV-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetViewportWScalingNV-videocoding
    此命令必须仅在视频编码范围之外调用。

  • VUID-vkCmdSetViewportWScalingNV-viewportCount-arraylength
    viewportCount 必须大于 0

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

VkPipelineViewportWScalingStateCreateInfoNVvkCmdSetViewportWScalingNV 都使用 VkViewportWScalingNV 来设置视口变换参数。

VkViewportWScalingNV 结构的定义如下:

// Provided by VK_NV_clip_space_w_scaling
typedef struct VkViewportWScalingNV {
    float    xcoeff;
    float    ycoeff;
} VkViewportWScalingNV;
  • xcoeffycoeff 分别是视口在 x 和 y 方向上的 W 缩放因子。

坐标变换

顶点的裁剪坐标来自着色器执行,其产生一个顶点坐标 Position

在裁剪坐标上进行透视除法会产生归一化设备坐标,然后进行视口变换(请参阅 控制视口),将这些坐标转换为帧缓冲区坐标

如果裁剪坐标中的顶点位置由下式给出:

则该顶点的归一化设备坐标为:

渲染通道变换

可以为渲染通道实例启用渲染通道变换。由顶点着色器执行产生的裁剪坐标 (xc, yc) 在 XY 平面中,以原点为中心旋转 0、90、180 或 270 度进行变换。

当启用渲染通道变换时,该变换应用于渲染通道的所有子通道的所有图元。变换后的裁剪坐标中的顶点位置由下式给出:

其中

  • θ 对于 VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR 为 0 度

  • θ 对于 VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR 为 90 度

  • θ 对于 VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR 为 180 度

  • θ 对于 VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR 为 270 度

变换后的顶点的归一化设备坐标为:

当为渲染通道实例启用渲染通道变换时,将启用以下附加特性:

上述的最终结果是,应用程序可以表现得好像是渲染到以VkSurfaceCapabilitiesKHR::currentTransform为方向的帧缓冲区。换句话说,应用程序可以表现得好像演示引擎将在渲染之后、呈现给用户之前执行交换链图像的转换。实际上,上述各种项目的转换是在渲染进行时由实现处理的。

控制视口

视口变换由所选视口的宽度和高度(以像素为单位),分别为 pxpy,及其中心 (ox, oy)(也以像素为单位)以及其深度范围最小值和最大值决定,它们确定了深度范围比例值 pz 和深度范围偏移值 oz(定义如下)。顶点的帧缓冲区坐标 (xf, yf) 和深度 zf 由下式给出:

xf = (px / 2) xd + ox

yf = (py / 2) yd + oy

zf = pz × zd + oz

可以使用多个视口,编号从零到 VkPhysicalDeviceLimits::maxViewports 减一。管线使用的视口数量由管线创建中使用的 VkPipelineViewportStateCreateInfo 结构的 viewportCount 成员控制。

xfyf 的精度有限,其中保留的小数位数由 VkPhysicalDeviceLimits::subPixelPrecisionBits 指定。当栅格化线段时,小数位数由 VkPhysicalDeviceLineRasterizationProperties::lineSubPixelPrecisionBits 指定。

VkPipelineViewportStateCreateInfo 结构定义如下:

// Provided by VK_VERSION_1_0
typedef struct VkPipelineViewportStateCreateInfo {
    VkStructureType                       sType;
    const void*                           pNext;
    VkPipelineViewportStateCreateFlags    flags;
    uint32_t                              viewportCount;
    const VkViewport*                     pViewports;
    uint32_t                              scissorCount;
    const VkRect2D*                       pScissors;
} VkPipelineViewportStateCreateInfo;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • flags 保留供将来使用。

  • viewportCount 是管线使用的视口数量。

  • pViewports 是指向 VkViewport 结构数组的指针,定义了视口变换。如果视口状态是动态的,则忽略此成员。

  • scissorCount剪裁的数量,并且必须与视口的数量匹配。

  • pScissors 是指向 VkRect2D 结构数组的指针,定义了相应视口的剪裁矩形边界。如果剪裁状态是动态的,则忽略此成员。

有效用法
  • VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216
    如果未启用 multiViewport 功能,则 viewportCount 必须不大于 1

  • VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217
    如果未启用 multiViewport 功能,则 scissorCount 必须不大于 1

  • VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218
    viewportCount 必须小于或等于 VkPhysicalDeviceLimits::maxViewports

  • VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219
    scissorCount 必须小于或等于 VkPhysicalDeviceLimits::maxViewports

  • VUID-VkPipelineViewportStateCreateInfo-x-02821
    pScissors 的任何元素的 offset 成员的 xy 成员必须大于或等于 0

  • VUID-VkPipelineViewportStateCreateInfo-offset-02822
    对于 pScissors 的任何元素,计算 (offset.x + extent.width) 必须不会导致有符号整数加法溢出

  • VUID-VkPipelineViewportStateCreateInfo-offset-02823
    对于 pScissors 的任何元素,计算 (offset.y + extent.height) 必须不会导致有符号整数加法溢出

  • VUID-VkPipelineViewportStateCreateInfo-scissorCount-04134
    如果 scissorCountviewportCount 都不是动态的,则 scissorCountviewportCount 必须相同

  • VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135
    如果图形管线是在设置了 VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT 的情况下创建的,则 viewportCount 必须0,否则 viewportCount 必须大于 0

  • VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136
    如果图形管线是在设置了 VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT 的情况下创建的,则 scissorCount 必须0,否则 scissorCount 必须大于 0

  • VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726
    如果在 pNext 链中包含的 VkPipelineViewportWScalingStateCreateInfoNV 结构的 viewportWScalingEnable 成员为 VK_TRUE,则 VkPipelineViewportWScalingStateCreateInfoNV 结构的 viewportCount 成员必须大于或等于 VkPipelineViewportStateCreateInfo::viewportCount

有效使用(隐式)

动态设置视口计数和视口,请调用:

// Provided by VK_VERSION_1_3
void vkCmdSetViewportWithCount(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    viewportCount,
    const VkViewport*                           pViewports);

或等效命令:

// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetViewportWithCountEXT(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    viewportCount,
    const VkViewport*                           pViewports);
  • commandBuffer 是将记录命令的命令缓冲区。

  • viewportCount 指定视口计数。

  • pViewports 指定用于绘制的视口。

当使用着色器对象进行绘制,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT 时创建时,此命令设置后续绘制命令的视口计数和视口状态。否则,此状态由用于创建当前活动管线的相应的 VkPipelineViewportStateCreateInfo::viewportCountpViewports 值指定。

有效用法
  • VUID-vkCmdSetViewportWithCount-None-08971
    以下条件中,至少有一个必须为真:

  • VUID-vkCmdSetViewportWithCount-viewportCount-03394
    viewportCount **必须** 在 1VkPhysicalDeviceLimits::maxViewports 之间,包含这两个值

  • VUID-vkCmdSetViewportWithCount-viewportCount-03395
    如果未启用 multiViewport 功能,则 viewportCount **必须** 为 1

  • VUID-vkCmdSetViewportWithCount-commandBuffer-04819
    commandBuffer **必须** 没有启用 VkCommandBufferInheritanceViewportScissorInfoNV::viewportScissor2D

有效使用(隐式)
  • VUID-vkCmdSetViewportWithCount-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetViewportWithCount-pViewports-parameter
    pViewports **必须** 是指向一个由 viewportCount 个有效的 VkViewport 结构组成的数组的有效指针

  • VUID-vkCmdSetViewportWithCount-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdSetViewportWithCount-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetViewportWithCount-videocoding
    此命令必须仅在视频编码范围之外调用。

  • VUID-vkCmdSetViewportWithCount-viewportCount-arraylength
    viewportCount 必须大于 0

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

动态设置剪裁计数和剪裁矩形边界,请调用

// Provided by VK_VERSION_1_3
void vkCmdSetScissorWithCount(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    scissorCount,
    const VkRect2D*                             pScissors);

或等效命令:

// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetScissorWithCountEXT(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    scissorCount,
    const VkRect2D*                             pScissors);
  • commandBuffer 是将记录命令的命令缓冲区。

  • scissorCount 指定剪裁计数。

  • pScissors 指定用于绘制的剪裁。

当使用着色器对象进行绘制,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT 时创建时,此命令设置后续绘制命令的剪裁计数和剪裁矩形边界状态。否则,此状态由用于创建当前活动管线的相应的 VkPipelineViewportStateCreateInfo::scissorCountpScissors 值指定。

有效用法
  • VUID-vkCmdSetScissorWithCount-None-08971
    以下条件中,至少有一个必须为真:

  • VUID-vkCmdSetScissorWithCount-scissorCount-03397
    scissorCount **必须** 在 1VkPhysicalDeviceLimits::maxViewports 之间,包含这两个值

  • VUID-vkCmdSetScissorWithCount-scissorCount-03398
    如果未启用 multiViewport 功能,则 scissorCount **必须** 为 1

  • VUID-vkCmdSetScissorWithCount-x-03399
    pScissors 的任何元素的 offset 成员的 xy 成员必须大于或等于 0

  • VUID-vkCmdSetScissorWithCount-offset-03400
    对于 pScissors 的任何元素,计算 (offset.x + extent.width) 必须不会导致有符号整数加法溢出

  • VUID-vkCmdSetScissorWithCount-offset-03401
    对于 pScissors 的任何元素,计算 (offset.y + extent.height) 必须不会导致有符号整数加法溢出

  • VUID-vkCmdSetScissorWithCount-commandBuffer-04820
    commandBuffer **必须** 没有启用 VkCommandBufferInheritanceViewportScissorInfoNV::viewportScissor2D

有效使用(隐式)
  • VUID-vkCmdSetScissorWithCount-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetScissorWithCount-pScissors-parameter
    pScissors **必须** 是指向一个由 scissorCountVkRect2D 结构组成的数组的有效指针

  • VUID-vkCmdSetScissorWithCount-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdSetScissorWithCount-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetScissorWithCount-videocoding
    此命令必须仅在视频编码范围之外调用。

  • VUID-vkCmdSetScissorWithCount-scissorCount-arraylength
    scissorCount **必须** 大于 0

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineViewportStateCreateFlags;

VkPipelineViewportStateCreateFlags 是用于设置掩码的位掩码类型,但目前保留以供将来使用。

一个 *预光栅化着色器阶段* **可以** 将每个图元定向到零个或多个视口。图元的目的地视口由最后一个活动的预光栅化着色器阶段选择,该阶段具有一个用 ViewportIndex(选择单个视口)或 ViewportMaskNV(选择多个视口)修饰的输出变量。视口变换使用与分配给 ViewportIndex 的值或 ViewportMaskNV 中设置的位对应的视口,并从每个图元的实现相关的顶点中获取。如果 ViewportIndexViewportMaskNV 中的任何位对于图元超出零到 viewportCount 减一的范围,或者如果最后一个活动的预光栅化着色器阶段由于流控制而未为图元的所有顶点分配值给 ViewportIndexViewportMaskNV,则此类图元的顶点的视口变换产生的值是**未定义的**。如果最后一个 预光栅化着色器阶段 没有用 ViewportIndexViewportMaskNV 修饰的输出,则视口变换使用编号为零的视口。

单个顶点 **可以** 在多个单独的图元中使用,例如 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP 中的图元。在这种情况下,视口变换分别应用于每个图元。

动态设置视口变换参数,请调用

// Provided by VK_VERSION_1_0
void vkCmdSetViewport(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstViewport,
    uint32_t                                    viewportCount,
    const VkViewport*                           pViewports);
  • commandBuffer 是将记录命令的命令缓冲区。

  • firstViewport 是由命令更新其参数的第一个视口的索引。

  • viewportCount 是由命令更新其参数的视口数量。

  • pViewports 是指向 VkViewport 结构数组的指针,该数组指定视口参数。

此命令为后续使用着色器对象进行绘制的命令,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_VIEWPORT 时,设置视口变换参数状态。否则,此状态由用于创建当前活动管线的 VkPipelineViewportStateCreateInfo::pViewports 值指定。

pViewports 的第 i 个元素获取的视口参数将替换视口索引为 firstViewport + i 的当前状态,其中 i[0, viewportCount) 范围内。

有效用法
  • VUID-vkCmdSetViewport-firstViewport-01223
    firstViewportviewportCount 的总和必须1VkPhysicalDeviceLimits::maxViewports 之间(包含边界值)。

  • VUID-vkCmdSetViewport-firstViewport-01224
    如果未启用 multiViewport 特性,则 firstViewport 必须0

  • VUID-vkCmdSetViewport-viewportCount-01225
    如果未启用 multiViewport 功能,则 viewportCount **必须** 为 1

  • VUID-vkCmdSetViewport-commandBuffer-04821
    commandBuffer **必须** 没有启用 VkCommandBufferInheritanceViewportScissorInfoNV::viewportScissor2D

有效使用(隐式)
  • VUID-vkCmdSetViewport-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetViewport-pViewports-parameter
    pViewports **必须** 是指向一个由 viewportCount 个有效的 VkViewport 结构组成的数组的有效指针

  • VUID-vkCmdSetViewport-commandBuffer-recording
    commandBuffer 必须处于记录状态

  • VUID-vkCmdSetViewport-commandBuffer-cmdpool
    分配 commandBufferVkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetViewport-videocoding
    此命令必须仅在视频编码范围之外调用。

  • VUID-vkCmdSetViewport-viewportCount-arraylength
    viewportCount 必须大于 0

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

VkPipelineViewportStateCreateInfovkCmdSetViewport 都使用 VkViewport 来设置视口变换参数。

VkViewport 结构定义如下:

// Provided by VK_VERSION_1_0
typedef struct VkViewport {
    float    x;
    float    y;
    float    width;
    float    height;
    float    minDepth;
    float    maxDepth;
} VkViewport;
  • xy 是视口的左上角坐标 (x,y)

  • widthheight 分别是视口的宽度和高度。

  • minDepthmaxDepth 是视口的深度范围。

尽管有这些名称,minDepth 可以小于、等于或大于 maxDepth

帧缓冲深度坐标 zf 可以使用定点或浮点表示形式。但是,如果深度/模板附件具有浮点深度分量,则必须使用浮点表示形式。如果使用 m 位定点表示形式,我们假设它将每个值 表示为 k (例如,1.0 在二进制中表示为全 1 的字符串),其中 k ∈ { 0, 1, …​, 2m-1 }

上述公式中显示的视口参数由以下值计算得出:

ox = x + width / 2

oy = y + height / 2

oz = minDepth (或者,如果 VkPipelineViewportDepthClipControlCreateInfoEXT::negativeOneToOneVK_TRUE,则为 (maxDepth + minDepth) / 2)

px = width

py = height

pz = maxDepth - minDepth (或者,如果 VkPipelineViewportDepthClipControlCreateInfoEXT::negativeOneToOneVK_TRUE,则为 (maxDepth - minDepth) / 2)

如果启用了渲染通道变换,则定义视口的 (px,py)(ox, oy) 值将按照渲染通道变换中的描述进行变换,然后再参与视口变换。

应用程序可以height 指定一个负值,这将导致在执行变换之前反转裁剪空间中的 y 坐标。当使用负的 height 时,应用程序还应该调整 y 值,使其指向视口的左下角而不是左上角。使用负的 height 允许应用程序避免反转来自最后一个光栅化前着色器阶段Position 输出的 y 分量。

实现相关的最大视口尺寸 的宽度和高度必须大于或等于可以创建并附加到帧缓冲区的最大图像的宽度和高度。

浮点视口边界以实现相关的精度表示。

有效用法
  • VUID-VkViewport-width-01770
    width 必须大于 0.0

  • VUID-VkViewport-width-01771
    width 必须小于或等于 VkPhysicalDeviceLimits::maxViewportDimensions[0]

  • VUID-VkViewport-apiVersion-07917
    如果未启用 VK_KHR_maintenance1 扩展,未启用 VK_AMD_negative_viewport_height 扩展,并且VkPhysicalDeviceProperties::apiVersion 小于 Vulkan 1.1,则 height 必须大于 0.0

  • VUID-VkViewport-height-01773
    height 的绝对值必须小于或等于 VkPhysicalDeviceLimits::maxViewportDimensions[1]

  • VUID-VkViewport-x-01774
    x 必须大于或等于 viewportBoundsRange[0]

  • VUID-VkViewport-x-01232
    (x + width) 必须小于或等于 viewportBoundsRange[1]

  • VUID-VkViewport-y-01775
    y 必须大于或等于 viewportBoundsRange[0]

  • VUID-VkViewport-y-01776
    y 必须小于或等于 viewportBoundsRange[1]

  • VUID-VkViewport-y-01777
    (y + height) 必须大于或等于 viewportBoundsRange[0]

  • VUID-VkViewport-y-01233
    (y + height) 必须小于或等于 viewportBoundsRange[1]

  • VUID-VkViewport-minDepth-01234
    如果未启用 VK_EXT_depth_range_unrestricted 扩展,则 minDepth 必须0.01.0 之间,包括 0.01.0

  • VUID-VkViewport-maxDepth-01235
    如果未启用 VK_EXT_depth_range_unrestricted 扩展,则 maxDepth 必须0.01.0 之间,包括 0.01.0