Vulkan 1.4

此提案描述了 Vulkan API 规范 1.4 版的内容。

1. 问题陈述

之前 Vulkan 的次要版本包含了一小部分所有供应商都同意在编写规范时支持的功能,而没有针对内容进行具体的规划。因此,虽然核心版本包含了一些有用的功能,但 API 中的几个非常有用的功能却长期未被纳入,从而降低了采用率并增加了行业内的碎片化。

此版本旨在成为第一个(希望是许多中的一个),采用不同的方法 - 提前规划以定义更引人注目的核心版本。

2. 解决方案空间

考虑了许多关于如何处理 Vulkan 1.4 的方法

  1. 一切照旧 - 包括广泛支持的任何功能,并实现剩余的任何功能

  2. 定义与沉浸式图形路线图并行的“核心路线图”

  3. 主要基于沉浸式图形路线图的子集定义核心版本

选项 (1) 可能可以与选项 (3) 类似的方式工作,但更自然 - 我们不会直接定义路线图,而是依赖于供应商随着时间的推移将功能逐步添加到他们的完整硬件目录中。但最终,由于工作组总是会审查并投票决定哪些功能是否包含在内,这实际上不会节省任何精力,并且很可能会导致某些功能无法入选,仅仅是因为一两个供应商没有在其自己的路线图中包含特定功能。

最初考虑选项 (2) 是基于嵌入式设备在某些情况下可能需要沉浸式部件上没有意义的特定功能,因此单独的路线图在某种程度上是一个有吸引力的选项。然而,经过考虑后,功能集几乎为零,并且与平台的关系更密切,而不是与特定市场相关。维护一个完全独立的路线图将需要付出大量的额外努力,最终可能会产生与选项 (3) 相同的结果。

选项 (3) 的好处是重用了已定义的路线图,允许工作组的这两个关键产品(路线图里程碑和核心版本)相互补充,而不是争夺资源。通过这样做,验证、规范编写、测试和新核心版本的实现将需要最少的精力,同时将一组已经过大量审查的功能标准化为新的核心版本。

此提案根据选项 (3) 定义了 Vulkan 1.4,使用 Vulkan 2022 和 Vulkan 2024 路线图作为起点。

3. 提案

此版本主要基于 2022 年路线图和 2024 年路线图中存在的功能,如果无法在所有供应商的所有当前支持的硬件上合理实施,则会省略这些功能。此版本中省略的功能仍然是将来版本规范中包含的候选功能。

3.1. 2022 年路线图

此版本需要 2022 年路线图中的以下功能

此版本需要 2022 年路线图中的以下限制

表 1. Vulkan 1.0 限制
限制名称 所需值 限制类型

maxImageDimension1D

8192

最小

maxImageDimension2D

8192

最小

maxImageDimensionCube

8192

最小

maxImageArrayLayers

2048

最小

maxUniformBufferRange

65536

最小

bufferImageGranularity

4096

最大

maxPerStageDescriptorUniformBuffers

15

最小

maxPerStageResources

200

最小

maxDescriptorSetUniformBuffers

90

最小,n × PerStage

maxDescriptorSetStorageBuffers

96

最小,n × PerStage

maxDescriptorSetStorageImages

144

最小,n × PerStage

maxFragmentCombinedOutputResources

16

最小

maxComputeWorkGroupInvocations

256

最小

maxComputeWorkGroupSize

(256,256,64)

最小

subTexelPrecisionBits

8

最小

mipmapPrecisionBits

6

最小

maxSamplerLodBias

14

最小

pointSizeGranularity

0.125

最大值,定点增量

lineWidthGranularity

0.5

最大值,定点增量

standardSampleLocations

VK_TRUE

布尔值

maxColorAttachments

8

最小

根据 2024 年路线图,maxColorAttachments 增加到 8,而不是 2022 年路线图要求的 7。
表 2. Vulkan 1.1 限制
限制名称 所需值 限制类型

subgroupSupportedStages

VK_SHADER_STAGE_COMPUTE_BIT
VK_SHADER_STAGE_FRAGMENT_BIT

标志

subgroupSupportedOperations

VK_SUBGROUP_FEATURE_BASIC_BIT
VK_SUBGROUP_FEATURE_VOTE_BIT
VK_SUBGROUP_FEATURE_ARITHMETIC_BIT
VK_SUBGROUP_FEATURE_BALLOT_BIT
VK_SUBGROUP_FEATURE_SHUFFLE_BIT
VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT
VK_SUBGROUP_FEATURE_QUAD_BIT *

标志

*只有当声明的子组大小为 4 或更高时,才支持VK_SUBGROUP_FEATURE_QUAD_BIT

Vulkan 1.4 不要求支持的子组大小大于 1,但如果供应商具有有意义的子组大小,则将支持以上所有功能。
表 3. Vulkan 1.2 限制
限制名称 所需值 限制类型

shaderSignedZeroInfNanPreserveFloat16

VK_TRUE*

布尔值

shaderSignedZeroInfNanPreserveFloat32

VK_TRUE

布尔值

*只有在支持 shaderFloat16 功能时,才支持shaderSignedZeroInfNanPreserveFloat16

VK_KHR_global_priority 扩展完全提升到 Vulkan 1.4。

3.2. 2024 年路线图

Vulkan 1.4 中需要以下来自 2024 年路线图的功能

Vulkan 1.4 中现在需要以下来自 2024 年路线图的限制

表 4. Vulkan 1.0 限制
限制名称 所需值 限制类型

maxBoundDescriptorSets

7

最小

maxColorAttachments

8

最小

timestampComputeAndGraphics

VK_TRUE

布尔值

以下扩展完全提升到 Vulkan 1.4

此外,VK_KHR_dynamic_rendering_local_read 被部分提升;实现必须支持存储资源的本地读取和单采样的颜色附件。读取深度/模板附件和多采样附件的支持受新的布尔值 dynamicRenderingLocalReadDepthStencilAttachmentsdynamicRenderingLocalReadMultisampledAttachments 属性控制。如果 dynamicRenderingLocalReadDepthStencilAttachmentsdynamicRenderingLocalReadMultisampledAttachmentsVK_TRUE,则表示存在扩展的完整功能。如果 dynamicRenderingLocalReadDepthStencilAttachmentsVK_FALSE,则表示实现不支持动态渲染中的深度/模板附件访问。如果 dynamicRenderingLocalReadMultisampledAttachmentsVK_FALSE,则表示实现不支持动态渲染中的多采样附件访问。

应用程序可以通过分配额外的颜色附件并将深度/模板值写入其中来解决缺少深度模板支持的问题。

3.3. 附加功能

虽然计划在路线图之外尽可能减少额外的功能(理想情况下仅限于维护扩展),但对于第一个版本,还需要一些额外的功能。这些功能混合了 Android 15 功能要求、Android Baseline 2022 配置文件以及在 2024 年路线图开发过程中遗漏的一些基于反馈的项目。

Vulkan 1.4 中需要支持以下附加功能

Vulkan 1.4 中需要以下附加限制

限制名称 所需值 限制类型

maxImageDimension3D

512

最小

pointSizeRange[1]

256 - pointSizeGranularity

最小

maxPushConstantsSize

256

最小

以下附加扩展完全提升到 Vulkan 1.4

还必须在 Vulkan 1.4 中通过在 subgroupSupportedOperations 中设置 VK_SUBGROUP_FEATURE_CLUSTERED_BITVK_SUBGROUP_FEATURE_ROTATE_CLUSTERED_BIT(与新提升的 VK_KHR_shader_subgroup_rotate 扩展的交互)来声明集群子组操作。

3.4. 流式传输

在早期版本的 Vulkan 中,一个没有明确解决方案的棘手问题是在同时渲染时向设备流式传输大量数据。在 OpenGL 和其他 API 中,采用主机指针的复制函数允许实现方式在执行传输的位置和方式上有很大的余地,从而允许实现方式使用主机复制、专用传输队列或其他解决方案,以确保渲染能够全速进行。

供应商可以自由公开专用的传输队列(如果有),并且最近 VK_EXT_host_image_copy 使驱动程序能够在没有单独的传输队列的情况下将主机复制作为一种选择进行声明。这两种方式中的任何一种都将为应用程序提供一种在主机和设备之间流式传输数据而不会中断渲染的方法。

Vulkan 1.4 施加了一些新的要求,以确保应用程序在所有 Vulkan 1.4 实现上都有可行的流式传输路径

  • VK_EXT_host_image_copy 已提升为核心,但支持其功能是可选的

  • 实现必须支持以下任一方式

    • hostImageCopy 功能;或

    • 支持 VK_QUEUE_TRANSFER_BIT 的其他队列。

  • 所有支持 VK_QUEUE_GRAPHICS_BITVK_QUEUE_COMPUTE_BIT 的队列也必须声明 VK_QUEUE_TRANSFER_BIT

应用程序在流式传输大量数据时应使用可用的任何选项,如果两者都可用,则选择最适合其用例的选项。应用程序应避免在正在渲染或执行其他高优先级工作负载的同一队列上执行大量传输。

3.5. 新功能结构

添加了一个新的功能结构,其中包含所有提升到核心的扩展的功能

typedef struct VkPhysicalDeviceVulkan14Features {
    VkStructureType     sType;
    void*               pNext;
    VkBool32            globalPriorityQuery;
    VkBool32            shaderSubgroupRotate;
    VkBool32            shaderSubgroupRotateClustered;
    VkBool32            shaderFloatControls2;
    VkBool32            shaderExpectAssume;
    VkBool32            rectangularLines;
    VkBool32            bresenhamLines;
    VkBool32            smoothLines;
    VkBool32            stippledRectangularLines;
    VkBool32            stippledBresenhamLines;
    VkBool32            stippledSmoothLines;
    VkBool32            vertexAttributeInstanceRateDivisor;
    VkBool32            vertexAttributeInstanceRateZeroDivisor;
    VkBool32            indexTypeUint8;
    VkBool32            dynamicRenderingLocalRead;
    VkBool32            maintenance5;
    VkBool32            maintenance6;
    VkBool32            pipelineProtectedAccess;
    VkBool32            pipelineRobustness;
    VkBool32            hostImageCopy;
    VkBool32            pushDescriptor;
} VkPhysicalDeviceVulkan14Features;

所有功能都具有与它们在提升扩展中的对应功能相同的含义和要求,但以下情况除外

  • 此外还需要 bresenhamLinesshaderSubgroupRotateClustered

  • pushDescriptor,它作为 VK_KHR_push_descriptor 功能的附加功能添加,并且是必需的

  • pipelineProtectedAccess,仅当支持 protectedMemory 功能时才需要

3.6. 新属性结构

添加了一个新的属性结构,其中包含所有提升到核心的扩展的属性

typedef struct VkPhysicalDeviceVulkan14Properties {
    VkStructureType                         sType;
    void*                                   pNext;
    // VK_KHR_line_rasterization
    uint32_t                                lineSubPixelPrecisionBits;
    // VK_KHR_vertex_attribute_divisor
    uint32_t                                maxVertexAttribDivisor;
    VkBool32                                supportsNonZeroFirstInstance;
    // VK_KHR_push_descriptor
    uint32_t                                maxPushDescriptors;
    // VK_KHR_dynamic_rendering_local_read
    VkBool32                                dynamicRenderingLocalReadDepthStencilAttachments;
    VkBool32                                dynamicRenderingLocalReadMultisampledAttachments;
    // VK_KHR_maintenance5
    VkBool32                                earlyFragmentMultisampleCoverageAfterSampleCounting;
    VkBool32                                earlyFragmentSampleMaskTestBeforeSampleCounting;
    VkBool32                                depthStencilSwizzleOneSupport;
    VkBool32                                polygonModePointSize;
    VkBool32                                nonStrictSinglePixelWideLinesUseParallelogram;
    VkBool32                                nonStrictWideLinesUseParallelogram;
    // VK_KHR_maintenance6
    VkBool32                                blockTexelViewCompatibleMultipleLayers;
    uint32_t                                maxCombinedImageSamplerDescriptorCount;
    VkBool32                                fragmentShadingRateClampCombinerInputs;
    // VK_EXT_pipeline_robustness
    VkPipelineRobustnessBufferBehavior      defaultRobustnessStorageBuffers;
    VkPipelineRobustnessBufferBehavior      defaultRobustnessUniformBuffers;
    VkPipelineRobustnessBufferBehavior      defaultRobustnessVertexInputs;
    VkPipelineRobustnessImageBehavior       defaultRobustnessImages;
    // VK_EXT_host_image_copy
    uint32_t                                copySrcLayoutCount;
    VkImageLayout*                          pCopySrcLayouts;
    uint32_t                                copyDstLayoutCount;
    VkImageLayout*                          pCopyDstLayouts;
    uint8_t                                 optimalTilingLayoutUUID[VK_UUID_SIZE];
    VkBool32                                identicalMemoryTypeRequirements;
} VkPhysicalDeviceVulkan14Properties;

所有属性都具有与它们在提升扩展中的对应属性相同的含义和所需限制,但新添加的 dynamicRenderingLocalReadDepthStencilAttachmentsdynamicRenderingLocalReadMultisampledAttachments 限制除外,它们是可选的,并且控制对动态渲染中深度/模板附件和多采样附件的本地读取的支持。