Android vulkan示例

vkCreateInstance

vkCreateInstance 是 Vulkan 应用程序的 ​基石函数,负责初始化全局环境、配置调试工具与平台适配扩展。其设计体现了 Vulkan 的显式控制理念------开发者需主动声明需求,而非依赖驱动隐式处理。正确使用该函数是构建高性能、跨平台图形应用的第一步。

vkCreateAndroidSurfaceKHR

  1. 获取 ANativeWindow
    通过 JNI 从 Android 应用层传递 Surface 对象,并转换为 ANativeWindow
c++ 复制代码
// Java 层通过 JNI 传递 Surface
extern "C" JNIEXPORT void JNICALL Java_com_example_app_setSurface(JNIEnv* env, jobject obj, jobject surface) {
    ANativeWindow* window = ANativeWindow_fromSurface(env, surface); // 转换为 ANativeWindow
}
  1. 创建 VkSurfaceKHR
    初始化 VkAndroidSurfaceCreateInfoKHR 结构体并调用函数:
c++ 复制代码
VkAndroidSurfaceCreateInfoKHR createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
createInfo.window = window; // 传入 ANativeWindow 指针

VkSurfaceKHR surface;
VkResult result = vkCreateAndroidSurfaceKHR(instance, &createInfo, nullptr, &surface);

成功时返回 VK_SUCCESS,失败则抛出错误(如 VK_ERROR_NATIVE_WINDOW_IN_USE_KHR

vkGetPhysicalDeviceQueueFamilyProperties

核心功能

  1. 获取队列族信息

    该函数返回物理设备支持的队列族列表,每个队列族包含以下属性:

    • **queueFlags**:标识队列支持的操作类型(图形、计算、传输等),通过 VkQueueFlagBits 枚举表示(如 VK_QUEUE_GRAPHICS_BIT 表示图形渲染支持)
    • **queueCount**:该队列族中可用的队列数量。例如,一个图形队列族可能包含多个独立的图形队列。
    • **minImageTransferGranularity**:定义图像传输操作的最小粒度,影响内存复制和布局转换的效率
  2. 多阶段调用模式

    与 Vulkan 的典型设计一致,需分两步调用:

    • 首次调用 :传入 pQueueFamilyPropertiesnullptr,获取队列族数量 queueFamilyCount
    • 二次调用 :分配足够内存后,传入 VkQueueFamilyProperties 数组,填充具体属性数据
    c++ 复制代码
    uint32_t queueFamilyCount;
    vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr);
    std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
    vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies.data());

应用场景

  1. 选择图形/计算队列
    遍历队列族属性,筛选支持所需功能的队列族索引。例如,查找支持图形操作的队列族
c++ 复制代码
int graphicsQueueFamilyIndex = -1;
for (uint32_t i = 0; i < queueFamilyCount; i++) {
    if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
        graphicsQueueFamilyIndex = i;
        break;
    }
}
  1. 窗口呈现队列兼容性检查
    在支持窗口系统的队列族中(如 VK_KHR_surface 扩展),需通过 vkGetPhysicalDeviceSurfaceSupportKHR 验证是否支持呈现(Present)操作
  2. 创建逻辑设备VkDeviceCreateInfo 中指定队列族的索引和优先级,例如为图形队列分配最高优先级
c++ 复制代码
VkDeviceQueueCreateInfo queueCreateInfo{};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = graphicsQueueFamilyIndex;
queueCreateInfo.queueCount = 1;
float queuePriority = 1.0f;  // 最高优先级
queueCreateInfo.pQueuePriorities = &queuePriority;

注意事项

  1. 队列族功能隔离 同一物理设备的队列族可能功能重叠(如多个队列族支持图形操作),但 Vulkan 禁止两队列族的功能集完全相同。
  2. 队列数量限制 每个队列族的 queueCount 受物理设备限制。例如,某些设备可能仅支持一个图形队列。
  3. 多线程优化 若队列族支持多队列(queueCount > 1),可通过多线程并行提交命令缓冲,提升 CPU 利用率。
  4. 跨平台兼容性 移动端设备(如 Android)通常仅需图形队列,而桌面端可能需分离图形、计算和传输队列以优化性能。

vkCreateDevice

核心功能

  1. 抽象物理设备
    逻辑设备是物理设备(如 GPU)的代理,通过它提交渲染命令、管理资源(如缓冲区、纹理),而无需直接操作硬件。例如,一个物理设备可能支持图形、计算和传输队列,但逻辑设备可以选择只启用图形队列
  2. 队列分配与管理
    在创建逻辑设备时需指定 队列族(Queue Family)​ 及其优先级,例如为图形队列分配最高优先级(1.0f),以优化 GPU 调度效率
  3. 扩展与特性配置 支持启用设备级扩展(如交换链扩展 VK_KHR_swapchain)和硬件特性(如几何着色器、多视口渲染)。

参数说明

函数原型如下:

c++ 复制代码
VkResult vkCreateDevice(
    VkPhysicalDevice physicalDevice,
    const VkDeviceCreateInfo* pCreateInfo,
    const VkAllocationCallbacks* pAllocator,
    VkDevice* pDevice
);
参数 说明
physicalDevice 目标物理设备句柄(通过 vkEnumeratePhysicalDevices 获取)
pCreateInfo 指向 VkDeviceCreateInfo 结构体的指针,包含队列配置、扩展和特性信息
pAllocator 自定义内存分配器(通常设为 nullptr 使用默认分配器)
pDevice 输出参数,返回创建的逻辑设备句柄
相关推荐
二流小码农1 小时前
鸿蒙开发:Canvas绘制之画笔对象Pen
android·ios·harmonyos
码农幻想梦2 小时前
18491 岛屿的数量
android·java·开发语言
技术宝哥3 小时前
Google 停止 AOSP 开源,安卓生态要“变天”?
android·开源协议
阿杰在学习3 小时前
基于OpenGL ES实现的Android人体热力图可视化库
android·前端·opengl
行墨3 小时前
Kotlin函数类型作为返回类型
android
今阳3 小时前
鸿蒙开发笔记-15-应用启动框架AppStartup
android·华为·harmonyos
_一条咸鱼_3 小时前
Android Compose 框架的颜色与形状之颜色管理深入剖析(四十一)
android
愤怒的代码3 小时前
Android 11 SystemUI 导入 Android studio 编译打包过程
android·android studio
倾云鹤5 小时前
okhttp3网络请求
android·网络
二流小码农5 小时前
鸿蒙开发:了解Canvas绘制
android·ios·harmonyos