Vulkan — 什么是跨平台API与渲染

作者: IT Sectr 发布日期: 2026-05-03 阅读时间: 9 分钟

Vulkan — 由Khronos Group联盟开发的用于在GPU上进行图形和计算工作的跨平台API。Vulkan提供对硬件的底层控制、多线程命令生成和可预测的性能。根据Khronos Group(2026年)的数据,Vulkan在98%的现代Android设备上得到支持。

要点

  • Vulkan — 跨平台GPU API,具有对硬件的底层控制
  • VkDeviceVkQueue提供多线程GPU命令发送
  • SPIR-V — 通用二进制着色器格式,从GLSL和HLSL编译
  • Vulkan Memory Allocator管理GPU内存的显式分配
  • Vulkan Ray Tracing(VK_KHR_ray_tracing)支持硬件光线追踪

什么是Vulkan?

Vulkan — 是一个底层、跨平台的用于图形处理器工作的API,由Khronos Group于2016年首次发布。Vulkan取代了OpenGL,提供显著更低的CPU开销、可预测的性能以及多线程命令生成的能力。

与OpenGL不同,在OpenGL中驱动程序在CPU上执行检查和同步,Vulkan将资源管理交给开发者。内存分配、通过信号量和屏障进行同步、创建管线——所有这些都显式控制。这种方法在CPU-bound场景中可提供高达50%的性能提升。

Vulkan支持Windows、Linux、Android、iOS(通过MoltenVK)、macOS(通过MoltenVK)、Nintendo Switch和游戏主机。根据Khronos Group(2026年)的数据,该API可在搭载NVIDIA、AMD、Intel、Qualcomm(Adreno)、ARM(Mali)和Apple(通过Metal层)GPU的设备上运行。Vulkan 1.4(2026年)增加了对Mesh Shaders和Video Encode API的支持。

Vulkan的历史

最初Vulkan以代号“glNext”开发——OpenGL的继任者。Vulkan 1.0(2016年)提供了具有显式内存管理、SPIR-V着色器和多线程队列的基础API。Vulkan 1.1(2018年)增加了Subgroup Operations和对16位类型的支持。Vulkan 1.2(2020年)引入了Buffer Device Address和Timeline Semaphores。

Vulkan 1.3(2022年)标准化了Dynamic Rendering和Graphics Pipeline Library。Vulkan 1.4(2026年)强制要求Mesh Shaders支持,并增加了用于H.264/HEVC/AV1硬件编码的Video Encode/Decode API。根据Khronos(2026年)的数据,Vulkan 1.4在所有新GPU上得到支持:NVIDIA RTX 50xx、AMD RX 9000和Intel Arc B系列。

Vulkan架构:设备和队列

Vulkan架构建立在硬件抽象层(HW layer)之上。应用程序通过逻辑设备(VkDevice)与物理设备(VkPhysicalDevice)交互。命令被发送到队列(VkQueue)中,每个队列属于特定的队列族(graphics、compute、transfer)。

VkInstance、VkDevice和VkQueue

VkInstance — Vulkan的根对象,存储有关验证层和扩展的信息。VkPhysicalDevice代表物理GPU,允许查询其属性、memory heaps和queue families。VkDevice — 具有显式请求的队列和扩展的逻辑设备。

cpp
// 创建Vulkan逻辑设备
VkDeviceCreateInfo devInfo {};
devInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
devInfo.queueCreateInfoCount = 1;
 
float queuePriority = 1.0f;
VkDeviceQueueCreateInfo queueInfo {};
queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueInfo.queueFamilyIndex = 0;
queueInfo.queueCount = 1;
queueInfo.pQueuePriorities = &queuePriority;
devInfo.pQueueCreateInfos = &queueInfo;
 
VkDevice device;
vkCreateDevice(physicalDevice, &devInfo,
    nullptr, &device);
 
VkQueue queue;
vkGetDeviceQueue(device, 0, 0, &queue);

vkCreateDevice函数使用指定的队列创建逻辑设备。VkQueue — 用于发送命令的队列描述符。如果相应的标志被队列族支持,一个队列可用于图形、计算和拷贝。队列优先级(0.0–1.0)影响竞争时的执行顺序。

VkMemory和VkBuffer — 内存管理

在Vulkan中,内存通过VkDeviceMemory显式分配。开发者从物理设备请求memory types(HOST_VISIBLE、DEVICE_LOCAL)并分配块。缓冲区(VkBuffer)和纹理(VkImage)没有自己的内存——它们通过vkBindBufferMemory绑定到分配的块。

Vulkan Memory Allocator(VMA)—— 来自AMD的库,简化了内存管理。VMA自动将小分配分组到大块中,管理碎片整理并选择合适的memory type。根据AMD(2025年)的数据,与手动管理相比,VMA将内存分配次数减少了50-100倍。

VkCommandPool和VkCommandBuffer

VkCommandPool管理命令缓冲区的内存。缓冲区(VkCommandBuffer)在CPU上编写并通过vkQueueSubmit发送到GPU。Vulkan支持primary和secondary缓冲区:primary直接发送,secondary可从primary调用以进行多线程命令构建。

命令编写以vkBeginCommandBuffer开始,以vkEndCommandBuffer结束。在它们之间写入渲染命令:vkCmdDraw、vkCmdDispatch、vkCmdCopyBuffer和用于同步的vkCmdPipelineBarrier。每个帧通过pool reset创建一个新的命令缓冲区。

通过Vulkan渲染:管线和命令

Vulkan中的渲染通过管线(VkPipeline)组织。与OpenGL不同,在OpenGL中管线状态全局变化,Vulkan使用VkPipeline — 一个预编译的管线,包含所有阶段:顶点输入、着色器、光栅化、深度模板和混合。

VkPipeline — 渲染管线

VkGraphicsPipelineCreateInfo描述完整管线:顶点和片段着色器、拓扑(triangle list、triangle strip)、光栅化器(fill mode、cull mode)、多重采样、深度模板测试、混合和视口设置。管线创建一次并重复使用——状态更改需要新管线或dynamic state。

cpp
// 配置图形管线
VkGraphicsPipelineCreateInfo pipelineInfo {};
pipelineInfo.sType =
    VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.stageCount = 2;
pipelineInfo.pStages = shaderStages;
pipelineInfo.pVertexInputState =&;
    vertexInputState;
pipelineInfo.pRasterizationState =&;
    rasterState;
 
VkPipeline graphicsPipeline;
vkCreateGraphicsPipelines(device,
    VK_NULL_HANDLE, 1, &pipelineInfo,
    nullptr, &graphicsPipeline);

Dynamic State(VK_DYNAMIC_STATE_VIEWPORT、VK_DYNAMIC_STATE_SCISSOR)允许在不创建新管线的情况下更改特定参数。Vulkan 1.4强制要求支持Dynamic State 3(VK_EXT_extended_dynamic_state_3),用于动态管理blend constants、depth bias和拓扑,从而减少项目中的管线数量。

Render Pass和Dynamic Rendering

VkRenderPass描述渲染通道的结构:使用哪些附件,如何清除和加载。Dynamic Rendering(VK_KHR_dynamic_rendering,从Vulkan 1.4起强制)简化了流程:渲染通道在命令缓冲区中通过vkCmdBeginRendering动态创建,无需预先的VkRenderPass对象。

根据Khronos(2026年)的数据,Dynamic Rendering将Vulkan初始化代码量减少30-40%,并降低管线排列组合的数量。对于复杂的延迟渲染技术(Deferred Shading),仍然方便使用带有多个subpass的经典VkRenderPass来处理G-buffer和光照。

Vulkan中的着色器:SPIR-V和GLSL

SPIR-V — Vulkan中通用的二进制着色器格式,由Khronos开发。着色器可以用GLSL、HLSL或Zink语言编写,并通过glslangValidator、dxc或Google Shaderc编译为SPIR-V。Vulkan不接受源代码形式的着色器——仅接受二进制SPIR-V。

Vulkan中的GLSL

Vulkan的GLSL与标准OpenGL GLSL不同。使用带有显式指定set和binding编号的块(layout),而不是内置变量。顶点属性通过location指定,uniform通过uniform blocks或缓冲区指定。Push constants(最多128字节)可用于无需缓冲区的快速数据传输。

glsl
// Vulkan/GLSL顶点着色器
#version 460
 
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
 
layout(binding = 0, set = 0)
uniform UniformBufferObject {
    mat4 modelViewProjection;
} ubo;
 
layout(location = 0) out vec3 outNormal;
 
void main() {
    gl_Position = ubo.modelViewProjection *
        vec4(inPosition, 1.0);
    outNormal = inNormal;
}

layout(set = N, binding = M)限定符——Vulkan GLSL与OpenGL的关键区别。Set对应描述符集(VkDescriptorSet),binding对应特定资源(缓冲区、纹理、采样器)。分为set可以在draw calls之间高效切换资源集,而无需绑定单个资源。

描述符和描述符集

VkDescriptorSet — 绑定到着色器的资源组(缓冲区、纹理、采样器)。描述符布局描述资源类型及其binding编号。描述符集通过vkUpdateDescriptorSets更新,并在draw calls之间重复使用。Vulkan 1.4支持VK_EXT_descriptor_buffer,用于从GPU直接访问描述符。

Push Constants — 一种无需创建描述符即可将少量数据(最多128字节)快速传输到着色器的机制。Push constants通过vkCmdPushConstants在命令缓冲区中指定。根据Khronos(2025年)的数据,在每帧超过1万次draw calls的频率下,使用push constants代替uniform buffers可将CPU开销降低10-15%。

不同平台上的Vulkan

Vulkan是唯一在所有主要平台上运行的API:Windows(通过官方ICD驱动程序)、Linux(RADV、AMDVLK、NVIDIA)、Android(Vulkan 1.3+,从Android 10起强制)以及通过MoltenVK(Vulkan → Metal转换层)在Apple设备上运行。

Android上的Vulkan

Android上,Vulkan对Android 10及更高版本是强制性的。Google推荐新项目使用Vulkan,特别是通过ARCore的高性能游戏和AR应用程序。Qualcomm Adreno和ARM Mali在Adreno 8xx和Mali-G720上提供对Vulkan 1.3的完整支持,包括硬件光线追踪。

根据Google(2026年)的数据,98%的Android设备(Android 10+)支持Vulkan。为了向后兼容,提供了ANGLE(Almost Native Graphics Layer Engine),它将OpenGL ES转换为Vulkan。这允许在Vulkan驱动程序上运行旧的OpenGL应用程序,性能提升高达20%。

在Android上,Vulkan在能效方面具有高优先级:在搭载Adreno 7xx+的设备上,在相同图形负载下,Vulkan应用程序比OpenGL ES节能25-40%。这使得Vulkan成为移动设备游戏的首选API。

通过MoltenVK在Apple上使用Vulkan

MoltenVK — 基于Metal的Vulkan实现,由LunarG和Valve开发。MoltenVK将Vulkan API调用转换为Metal,在iOS和macOS上支持Vulkan 1.2。MoltenVK的性能接近原生Metal:转换开销根据场景为5-15%。

根据LunarG(2025年)的数据,MoltenVK被用于CrossOver(Mac版Wine)在macOS上运行Windows游戏。macOS上的Dota 2、Civilization VI和Baldur’s Gate 3通过MoltenVK在M3/M4上以30-60 FPS的性能运行。MoltenVK支持MetalFX upscaling以提升性能。

Vulkan光线追踪

VK_KHR_ray_tracing — Vulkan中的硬件光线追踪扩展,从Vulkan 1.4起强制使用。支持带有RT核心的GPU:NVIDIA RTX 20xx/30xx/40xx/50xx、AMD RX 6000+/9000、Intel Arc A/B。Vulkan RT提供VkAccelerationStructure、VkRayTracingPipeline和Shader Binding Table。

Vulkan Ray Tracing支持实时反射、阴影、环境光遮蔽和全局光照。根据Khronos(2026年)的数据,在NVIDIA RTX 5090上,Vulkan Ray Tracing在参考质量场景中每秒执行高达1000亿条光线。对于便携式平台,Vulkan RT通过模糊减少和时域降噪进行缩放。

常见问题

什么是Vulkan,它与OpenGL有何不同?

Vulkan — 具有显式资源管理的底层跨平台GPU API。与OpenGL不同,它提供对内存、同步和多线程的控制,在CPU-bound场景中性能提升高达50%。

Vulkan在哪些平台上运行?

Vulkan可以在Windows、Linux、Android、Nintendo Switch以及通过MoltenVK(转换为Metal)在iOS/macOS上运行。支持NVIDIA、AMD、Intel、Qualcomm、ARM和Apple(通过MoltenVK)的GPU。

Vulkan中的SPIR-V是什么?

SPIR-V — Vulkan的通用二进制着色器格式。着色器用GLSL或HLSL编写,编译为SPIR-V并提交给Vulkan。这确保了对着色器编写语言的独立性和可预测的编译性能。

Vulkan是否支持光线追踪?

是的,通过VK_KHR_ray_tracing——从Vulkan 1.4起强制使用的扩展。支持带有RT核心的GPU:NVIDIA RTX、AMD RX 6000+、Intel Arc。Vulkan RT提供BVH结构加速、Shader Binding Table和硬件光线相交。

开始使用Vulkan困难吗?

由于显式内存管理、同步和管线,入门门槛高于OpenGL或DirectX 11。Khronos提供Vulkan Tutorial、Vulkan Samples和Vulkan Guide。绘制第一个三角形大约需要500行代码。

总结

  • Vulkan — 来自Khronos Group的跨平台底层GPU API
  • 显式管理内存、同步和队列可减少CPU开销
  • VkPipeline — 用于图形和计算的预编译管线
  • SPIR-V — 从GLSL和HLSL编译的二进制着色器格式
  • Dynamic Rendering(Vulkan 1.4)无需VkRenderPass即可简化Render Pass的创建
  • MoltenVK确保Vulkan通过Metal在iOS和macOS上运行
  • Vulkan 1.4增加了Mesh Shaders、Video Encode API和强制光线追踪

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读