这个扩展允许在任意的VK_OBJECT上绑定若干个8字节的数据。 主要用法是:
- 通过vkCreatePrivateDataSlotEXT创建一个slot,这个slot内部结构是不透明的,但是实际上里面就是一个index(应用层不可见)
- 这个slot可以被作为索引访问修改一个VK_OBJECT上的PRIVATE_DATA
问题1: 为什么Index要做成不透明的
这个Index实际上是存放在vkDevice上的一个成员变量(驱动层), 每次创建一个slot,这个index就会自增1。
这样可以避免不同的Layer申请到同一个Index。
每个Layer和应用每次调用vkCreatePrivateDataSlotEXT都会创建一个自增的index的slot。
问题2: 数据存放在哪, 数据结构是什么
数据实际存放在所有vulkan object的基类 vk_object上,数据结构是sparse array。
通过index可以稀疏的创建和删除数据。
问题3:为什么API需要传入ObjectType
既然PrivateData在所有的VK_OBJECT上,理论上是可以在任何的VK_OBJECT上绑定数据,为什么API需要传入ObjectType
// Provided by VK_VERSION_1_3
VkResult vkSetPrivateData(
    VkDevice                                    device,
    VkObjectType                                objectType, // ???Why
    uint64_t                                    objectHandle,
    VkPrivateDataSlot                           privateDataSlot,
    uint64_t                                    data);
因为Swapchain似乎比较特殊,具体哪里特殊暂时还不理解,至少对swapchain有额外的处理。
   if (objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
   ...
      mtx_lock(&device->swapchain_private_mtx);
      VkResult result = get_swapchain_private_data_locked(device, objectHandle,
                                                          slot, private_data);
      mtx_unlock(&device->swapchain_private_mtx);
      return result;
   }
   struct vk_object_base *obj =
      vk_object_base_from_u64_handle(objectHandle, objectType);
核心接口
核心的几个内部实现就在这里了。
VkPrivateDataSlot的数据结构
struct vk_private_data_slot {
   struct vk_object_base base;
   uint32_t index; // 一个Slot实际上只是一个VkObject + uint32_Index
};
VK_DEFINE_NONDISP_HANDLE_CASTS(vk_private_data_slot, base,
                               VkPrivateDataSlot,
                               VK_OBJECT_TYPE_PRIVATE_DATA_SLOT);
Slot的创建
VkResult
vk_private_data_slot_create(struct vk_device *device,
                            const VkPrivateDataSlotCreateInfo* pCreateInfo,
                            const VkAllocationCallbacks* pAllocator,
                            VkPrivateDataSlot* pPrivateDataSlot)
                            {
    vk_object_base_init(device, &slot->base,
                       VK_OBJECT_TYPE_PRIVATE_DATA_SLOT);
    // 可以看到index = device->private_data_next_index++ 
    slot->index = p_atomic_inc_return(&device->private_data_next_index);
}