Vulkan 学习(2)---- Vulkan Instance

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 , 要么指向其他结构体来扩展该结构体
  • flagsVkInstanceCreateFlagBits所表示的位域值,用于设置 VkInstance 的行为
  • pApplicationInfo 要么是 nullptr, 要么指向应用信息结构体,用于应用细节设置
  • enabledLayerCount 激活的 layer 数量
  • ppEnabledLayerNames 指向数量为 enabledLayerCountlayer 字符串数组,用于设置要激活的 layer
  • enabledExtensionCount 激活 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 版本

其中 pApplicationNameapplicationVersionpEngineNameengineVersion 这几个值随便设置,甚至可以不设置,空值都可以,这些参数不影响实例的创建。

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 的 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 中的 enabledExtensionCountppEnabledExtensionNames 就是用于配置此类 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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值