Mesa | VK_EXT_PRIVATE_DATA的实现 | Blurred code

Mesa | VK_EXT_PRIVATE_DATA的实现

2024/09/02

LastMod:2024/09/02

Categories: Mesa

这个扩展允许在任意的VK_OBJECT上绑定若干个8字节的数据。 主要用法是:

问题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);
}