vkCreateInstance
vkCreateInstance
是 Vulkan 应用程序的 基石函数,负责初始化全局环境、配置调试工具与平台适配扩展。其设计体现了 Vulkan 的显式控制理念------开发者需主动声明需求,而非依赖驱动隐式处理。正确使用该函数是构建高性能、跨平台图形应用的第一步。
vkCreateAndroidSurfaceKHR
- 获取 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
}
- 创建 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
核心功能
-
获取队列族信息
该函数返回物理设备支持的队列族列表,每个队列族包含以下属性:
- **
queueFlags
**:标识队列支持的操作类型(图形、计算、传输等),通过VkQueueFlagBits
枚举表示(如VK_QUEUE_GRAPHICS_BIT
表示图形渲染支持) - **
queueCount
**:该队列族中可用的队列数量。例如,一个图形队列族可能包含多个独立的图形队列。 - **
minImageTransferGranularity
**:定义图像传输操作的最小粒度,影响内存复制和布局转换的效率
- **
-
多阶段调用模式
与 Vulkan 的典型设计一致,需分两步调用:
- 首次调用 :传入
pQueueFamilyProperties
为nullptr
,获取队列族数量queueFamilyCount
- 二次调用 :分配足够内存后,传入
VkQueueFamilyProperties
数组,填充具体属性数据
c++uint32_t queueFamilyCount; vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr); std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount); vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies.data());
- 首次调用 :传入
应用场景
- 选择图形/计算队列
遍历队列族属性,筛选支持所需功能的队列族索引。例如,查找支持图形操作的队列族
c++
int graphicsQueueFamilyIndex = -1;
for (uint32_t i = 0; i < queueFamilyCount; i++) {
if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
graphicsQueueFamilyIndex = i;
break;
}
}
- 窗口呈现队列兼容性检查
在支持窗口系统的队列族中(如VK_KHR_surface
扩展),需通过vkGetPhysicalDeviceSurfaceSupportKHR
验证是否支持呈现(Present)操作 - 创建逻辑设备 在
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;
注意事项
- 队列族功能隔离 同一物理设备的队列族可能功能重叠(如多个队列族支持图形操作),但 Vulkan 禁止两队列族的功能集完全相同。
- 队列数量限制 每个队列族的
queueCount
受物理设备限制。例如,某些设备可能仅支持一个图形队列。 - 多线程优化 若队列族支持多队列(
queueCount > 1
),可通过多线程并行提交命令缓冲,提升 CPU 利用率。 - 跨平台兼容性 移动端设备(如 Android)通常仅需图形队列,而桌面端可能需分离图形、计算和传输队列以优化性能。
vkCreateDevice
核心功能
- 抽象物理设备
逻辑设备是物理设备(如 GPU)的代理,通过它提交渲染命令、管理资源(如缓冲区、纹理),而无需直接操作硬件。例如,一个物理设备可能支持图形、计算和传输队列,但逻辑设备可以选择只启用图形队列 - 队列分配与管理
在创建逻辑设备时需指定 队列族(Queue Family) 及其优先级,例如为图形队列分配最高优先级(1.0f
),以优化 GPU 调度效率 - 扩展与特性配置 支持启用设备级扩展(如交换链扩展
VK_KHR_swapchain
)和硬件特性(如几何着色器、多视口渲染)。
参数说明
函数原型如下:
c++
VkResult vkCreateDevice(
VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice
);
参数 | 说明 |
---|---|
physicalDevice |
目标物理设备句柄(通过 vkEnumeratePhysicalDevices 获取) |
pCreateInfo |
指向 VkDeviceCreateInfo 结构体的指针,包含队列配置、扩展和特性信息 |
pAllocator |
自定义内存分配器(通常设为 nullptr 使用默认分配器) |
pDevice |
输出参数,返回创建的逻辑设备句柄 |