Overview
Vulkan
实例是 Vukan API
的一个基本概念,它是连接 Vulkan
库和应用程序之间的桥梁,用于初始化 Vulkan
库,
创建 Vulkan
库实例涉及向驱动程序提供应用程序的一些细节,比如应用程序的信息和引擎信息等
在 Vulkan
中,实例(vkInstance
)是存储所有每个应用程序状态的对象,应用程序必须在执行其他Vulkan
操作之前创建一个Vulkan
实例
这个类似于OpenGl-ES
上下文的概念,一个实例代表一整个Vulkan
环境(或者上下文)。不同的Vulkan
环境能够获取到不同的 Vulkan
的功能特性
VkInstance 创建
VkInstance
的关键结构是 VkInstanceCreateInfo
:
typedef struct VkInstanceCreateInfo {
VkStructureType sType;
const void* pNext;
VkInstanceCreateFlags flags;
const VkApplicationInfo* pApplicationInfo;
uint32_t enabledLayerCount;
const char* const* ppEnabledLayerNames;
uint32_t enabledExtensionCount;
const char* const* ppEnabledExtensionNames;
} VkInstanceCreateInfo;
sType
该结构体类型的枚举值,必须是VkStructureType::VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
pNext
要么是 nullptr , 要么指向其他结构体来扩展该结构体flags
是VkInstanceCreateFlagBits
所表示的位域值,用于设置VkInstance
的行为pApplicationInfo
要么是nullptr
, 要么指向应用信息结构体,用于应用细节设置enabledLayerCount
激活的layer
数量ppEnabledLayerNames
指向数量为enabledLayerCount
的layer
字符串数组,用于设置要激活的 layerenabledExtensionCount
激活instance
扩展的数量ppEnabledExtensionNames
指向数量为 enabledExtensionCount 的扩展字符串数组,用于设置要激活的 instance 扩展
VkApplicationInfo
typedef struct VkApplicationInfo {
VkStructureType sType;
const void* pNext;
const char* pApplicationName;
uint32_t applicationVersion;
const char* pEngineName;
uint32_t engineVersion;
uint32_t apiVersion;
} VkApplicationInfo;
sType
是该结构体的类型枚举值, 必须 是VkStructureType::VK_STRUCTURE_TYPE_APPLICATION_INFO
pNext
要么是 NULL 要么指向其他结构体来扩展该结构体pApplicationName
要么是 NULL 要么指向一个以空字符为结尾的 UTF-8 字符串,用于表示用户自定义应用名称applicationVersion
一个无符号整型,用于用户自定义应用版本pEngineName
要么是 nullptr 要么指向一个以空字符为结尾的 UTF-8 字符串,用于表示用户自定义引擎名称engineVersion
一个无符号整型,用于用户自定义引擎版本apiVersion
是应用打算使用的 Vulkan 的最高 核心 版本,并且忽略 apiVersion 的 patch 版本
其中 pApplicationName
、 applicationVersion
、 pEngineName
和 engineVersion
这几个值随便设置,甚至可以不设置,空值都可以,这些参数不影响实例的创建。
而 apiVersion
参数是最为重要的核心参数 ,当创建实例时,该参数用于指定此实例环境中 Vulkan 的核心版本号
如何设置了错误的 Vulkan 版本,可能导致一些功能无法使用
Vulkan 1.0
主要提供光栅化图形和并行计算的功能。对应VK_API_VERSION_1_0
Vulkan 1.1
主要为Vulkan 1.0
不完善的地方进行补全。对应 VK_API_VERSION_1_1
Vulkan 1.2
主要提供硬件光追的功能, 对应VK_API_VERSION_1_2
Vulkan 1.3
主要提供动态光栅化图形的功能,对应VK_API_VERSION_1_3
Vulkan Layer
Vulkan 的 Layer 层是一种重要的机制,允许开发者在 Vulkan API
的核心功能上插入额外的功能和工具
Layer 主要的特点是模块化,可以根据需要加载和卸载,开发者可以选择在应用程序初始化时启用哪些层
比如你添加了验证层 VK_LAYER_KHRONOS_validation
,如果在执行阶段发生了使用错误, Layer 会输出错误信息,帮助开发者定位错误
目前 Vulkan
支持的层如下:
VK_LAYER_KHRONOS_validation
Vulkan API 使用 GFXReconstruct 捕获应用的 Vulkan 指令VK_LAYER_LUNARG_gfxreconstruct
输出调用的 API 和传入的参数VK_LAYER_LUNARG_api_dump
帮助测试硬件的性能,而不需要物理接触每个设备。该 层 将会覆盖从 GPU 查询到的数据VK_LAYER_LUNARG_monitor
在应用界面的标题处显示帧率VK_LAYER_LUNARG_screenshot
将显示的画面帧输出到一个图片文件中VK_LAYER_KHRONOS_synchronization2
使用系统实现的 VK_KHR_synchronization2 扩展,而不是驱动实现的VK_LAYER_KHRONOS_shader_object
使用系统实现的 VK_EXT_shader_object 扩展,而不是驱动实现的
可以通过 vkEnumerateInstanceLayerProperties
函数获取系统中 Vulkan 支持的 Layer
void vulkanEnumerateInfo() {
uint32_t layer_property_count = 0;
vkEnumerateInstanceLayerProperties(&layer_property_count, nullptr);
std::cout << "vulkan support layers: " << layer_property_count << std::endl;
std::vector<VkLayerProperties> layer_properties(layer_property_count);
vkEnumerateInstanceLayerProperties(&layer_property_count, layer_properties.data());
for (auto& vkProp : layer_properties) {
std::cout << "===============================================" << std::endl;
std::cout << "vk layername:" << vkProp.layerName << std::endl;
std::cout << "vk specVersion:" << vkProp.specVersion << std::endl;
std::cout << "vk implementationVersion:" << vkProp.implementationVersion << std::endl;
std::cout << "vk description:" << vkProp.description << std::endl;
}
}
在windows 上输出结果:
vulkan support layers: 9
===============================================
vk layername:VK_LAYER_LUNARG_api_dump
vk specVersion:4206882
vk implementationVersion:2
vk description:LunarG API dump layer
===============================================
vk layername:VK_LAYER_LUNARG_gfxreconstruct
vk specVersion:4206882
vk implementationVersion:4194309
vk description:GFXReconstruct Capture Layer Version 1.0.5
===============================================
vk layername:VK_LAYER_KHRONOS_synchronization2
vk specVersion:4206882
vk implementationVersion:1
vk description:Khronos Synchronization2 layer
===============================================
vk layername:VK_LAYER_KHRONOS_validation
vk specVersion:4206882
vk implementationVersion:1
vk description:Khronos Validation Layer
===============================================
vk layername:VK_LAYER_LUNARG_monitor
vk specVersion:4206882
vk implementationVersion:1
vk description:Execution Monitoring Layer
===============================================
vk layername:VK_LAYER_LUNARG_screenshot
vk specVersion:4206882
vk implementationVersion:1
vk description:LunarG image capture layer
===============================================
vk layername:VK_LAYER_KHRONOS_profiles
vk specVersion:4206882
vk implementationVersion:1
vk description:Khronos Profiles layer
===============================================
vk layername:VK_LAYER_KHRONOS_shader_object
vk specVersion:4206882
vk implementationVersion:1
vk description:Khronos Shader object layer
===============================================
vk layername:VK_LAYER_LUNARG_crash_diagnostic
vk specVersion:4206882
vk implementationVersion:1
vk description:Crash Diagnostic Layer is a crash/hang debugging tool that helps determines GPU progress in a Vulkan application.
Vulkan Extension
Vulkan Extensions
(instance Extension)是对 Vulkan API
的功能扩展,它们允许硬件制造商、平台开发者和第三方提供额外的功能和特性,这些功能和特性不包含在核心 Vulkan
规范中
在Vulkan
中有两类拓展:
Instance
扩展 与使用 GPU 设备无关,与 Vulkan 环境有关。VkInstanceCreateInfo
中的enabledExtensionCount
和ppEnabledExtensionNames
就是用于配置此类 Instance 扩展Device Extension
与使用哪一个 GPU 设备有关,不同厂家的 GPU 设备会支持不同的设备扩展
VkInstance
支持的实例扩展可以通过 vkEnumerateInstanceExtensionProperties
函数获取
void vulkanEnumerateExtension() {
uint32_t extension_property_count = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extension_property_count, nullptr);
std::cout << "vulkan support extensions: " << extension_property_count << std::endl;
std::vector<VkExtensionProperties> extension_properties(extension_property_count);
vkEnumerateInstanceExtensionProperties(nullptr, &extension_property_count, extension_properties.data());
for (auto& vkExtension : extension_properties) {
std::cout << "===============================================" << std::endl;
std::cout << "vk extensionName:" << vkExtension.extensionName << std::endl;
std::cout << "vk specVersion:" << vkExtension.specVersion << std::endl;
}
}
windows 上输出结果:
vulkan support extensions: 13
===============================================
vk extensionName:VK_KHR_surface
vk specVersion:25
===============================================
vk extensionName:VK_KHR_win32_surface
vk specVersion:5
===============================================
vk extensionName:VK_KHR_external_memory_capabilities
vk specVersion:1
===============================================
vk extensionName:VK_KHR_external_semaphore_capabilities
vk specVersion:1
===============================================
vk extensionName:VK_KHR_external_fence_capabilities
vk specVersion:1
===============================================
vk extensionName:VK_KHR_get_physical_device_properties2
vk specVersion:2
===============================================
vk extensionName:VK_KHR_get_surface_capabilities2
vk specVersion:1
===============================================
vk extensionName:VK_KHR_device_group_creation
vk specVersion:1
===============================================
vk extensionName:VK_EXT_swapchain_colorspace
vk specVersion:4
===============================================
vk extensionName:VK_EXT_debug_utils
vk specVersion:2
===============================================
vk extensionName:VK_EXT_debug_report
vk specVersion:10
===============================================
vk extensionName:VK_KHR_portability_enumeration
vk specVersion:1
===============================================
vk extensionName:VK_LUNARG_direct_driver_loading
vk specVersion:1
VK_KHR_surface
代表窗口通用平面扩展
VK_KHR_win32_surface
适配win32 平面的窗口平面拓展
VK_{vender}_{platform}_surface
代表各个平台各自的窗口平面(各自平台适配到通用平面)
比如:
VK_KHR_win32_surface
为 Windows 平台,供应商为 Khronos
VK_KHR_android_surface
为 Android 平台,供应商为 Khronos
创建 Vulkan
实例的代码:
void vulkanCreateInstance() {
VkInstance instance = nullptr;
std::vector<const char*> instance_extensions;
instance_extensions.push_back("VK_KHR_surface");
instance_extensions.push_back("VK_KHR_win32_surface");//win32
std::vector<const char*> instance_layers;
instance_layers.push_back("VK_LAYER_KHRONOS_validation");//添加验证层
VkApplicationInfo appInfo;
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pNext = nullptr;
appInfo.pApplicationName = "testvulkandemo";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "demo";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_MAKE_VERSION(1, 0, 0);
VkInstanceCreateInfo instanceCreateInfo;
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.pNext = nullptr;
instanceCreateInfo.pApplicationInfo = &appInfo;
instanceCreateInfo.enabledLayerCount = static_cast<uint32_t>(instance_layers.size());
instanceCreateInfo.ppEnabledLayerNames = instance_layers.data();
instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(instance_extensions.size());
instanceCreateInfo.ppEnabledExtensionNames = instance_extensions.data();
VkResult result = vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
if (result != VK_SUCCESS) {
std::cout << "vkInstance create failed!." << std::endl;
}
std::cout << "vkInstance create success!." << std::endl;
vkDestroyInstance(instance, nullptr);
}