vulkan: pass VK_LAYER_FUNCTION_DATA_CALLBACK to layers
VK_LAYER_FUNCTION_DATA_CALLBACK effectively allows us to pass
driver::SetDataInternal to layers. It will be called on handles of
potentially unknown types. Add two internal types
VK_DEFINE_HANDLE(InstanceDispatchable)
VK_DEFINE_HANDLE(DeviceDispatchable)
in driver namespace for type safety.
Bug: 28015368
Change-Id: I7389829a7d8c374197cd7046973777b49e436961
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp
index 4e19af5..eeb32d4 100644
--- a/vulkan/libvulkan/api.cpp
+++ b/vulkan/libvulkan/api.cpp
@@ -431,6 +431,11 @@
uint32_t count,
const VkAllocationCallbacks& allocator);
+ static VKAPI_ATTR VkResult SetInstanceLoaderData(VkInstance instance,
+ void* object);
+ static VKAPI_ATTR VkResult SetDeviceLoaderData(VkDevice device,
+ void* object);
+
static VKAPI_ATTR VkBool32
DebugReportCallback(VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT obj_type,
@@ -454,8 +459,8 @@
PFN_vkGetDeviceProcAddr get_device_proc_addr_;
union {
- VkLayerInstanceCreateInfo instance_chain_info_;
- VkLayerDeviceCreateInfo device_chain_info_;
+ VkLayerInstanceCreateInfo instance_chain_info_[2];
+ VkLayerDeviceCreateInfo device_chain_info_[2];
};
VkExtensionProperties* driver_extensions_;
@@ -616,18 +621,19 @@
void LayerChain::ModifyCreateInfo(VkInstanceCreateInfo& info) {
if (layer_count_) {
- const ActiveLayer& layer = layers_[0];
+ auto& link_info = instance_chain_info_[1];
+ link_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+ link_info.pNext = info.pNext;
+ link_info.function = VK_LAYER_FUNCTION_LINK;
+ link_info.u.pLayerInfo = &layers_[0].instance_link;
- instance_chain_info_.sType =
- VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
- instance_chain_info_.function = VK_LAYER_FUNCTION_LINK;
- // TODO fix vk_layer_interface.h and get rid of const_cast?
- instance_chain_info_.u.pLayerInfo =
- const_cast<VkLayerInstanceLink*>(&layer.instance_link);
+ auto& cb_info = instance_chain_info_[0];
+ cb_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+ cb_info.pNext = &link_info;
+ cb_info.function = VK_LAYER_FUNCTION_DATA_CALLBACK;
+ cb_info.u.pfnSetInstanceLoaderData = SetInstanceLoaderData;
- // insert layer info
- instance_chain_info_.pNext = info.pNext;
- info.pNext = &instance_chain_info_;
+ info.pNext = &cb_info;
}
if (override_layers_.Count()) {
@@ -643,17 +649,19 @@
void LayerChain::ModifyCreateInfo(VkDeviceCreateInfo& info) {
if (layer_count_) {
- const ActiveLayer& layer = layers_[0];
+ auto& link_info = device_chain_info_[1];
+ link_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
+ link_info.pNext = info.pNext;
+ link_info.function = VK_LAYER_FUNCTION_LINK;
+ link_info.u.pLayerInfo = &layers_[0].device_link;
- device_chain_info_.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
- device_chain_info_.function = VK_LAYER_FUNCTION_LINK;
- // TODO fix vk_layer_interface.h and get rid of const_cast?
- device_chain_info_.u.pLayerInfo =
- const_cast<VkLayerDeviceLink*>(&layer.device_link);
+ auto& cb_info = device_chain_info_[0];
+ cb_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
+ cb_info.pNext = &link_info;
+ cb_info.function = VK_LAYER_FUNCTION_DATA_CALLBACK;
+ cb_info.u.pfnSetDeviceLoaderData = SetDeviceLoaderData;
- // insert layer info
- device_chain_info_.pNext = info.pNext;
- info.pNext = &device_chain_info_;
+ info.pNext = &cb_info;
}
if (override_layers_.Count()) {
@@ -890,6 +898,24 @@
allocator.pfnFree(allocator.pUserData, layers);
}
+VkResult LayerChain::SetInstanceLoaderData(VkInstance instance, void* object) {
+ driver::InstanceDispatchable dispatchable =
+ reinterpret_cast<driver::InstanceDispatchable>(object);
+
+ return (driver::SetDataInternal(dispatchable, &driver::GetData(instance)))
+ ? VK_SUCCESS
+ : VK_ERROR_INITIALIZATION_FAILED;
+}
+
+VkResult LayerChain::SetDeviceLoaderData(VkDevice device, void* object) {
+ driver::DeviceDispatchable dispatchable =
+ reinterpret_cast<driver::DeviceDispatchable>(object);
+
+ return (driver::SetDataInternal(dispatchable, &driver::GetData(device)))
+ ? VK_SUCCESS
+ : VK_ERROR_INITIALIZATION_FAILED;
+}
+
VkBool32 LayerChain::DebugReportCallback(VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT obj_type,
uint64_t obj,
diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h
index 22db93f..5543792 100644
--- a/vulkan/libvulkan/driver.h
+++ b/vulkan/libvulkan/driver.h
@@ -64,6 +64,9 @@
namespace driver {
+VK_DEFINE_HANDLE(InstanceDispatchable)
+VK_DEFINE_HANDLE(DeviceDispatchable)
+
struct InstanceData {
InstanceData(const VkAllocationCallbacks& alloc)
: opaque_api_data(),
@@ -127,12 +130,15 @@
template <typename DispatchableType>
void StaticAssertDispatchable(DispatchableType) {
- static_assert(std::is_same<DispatchableType, VkInstance>::value ||
- std::is_same<DispatchableType, VkPhysicalDevice>::value ||
- std::is_same<DispatchableType, VkDevice>::value ||
- std::is_same<DispatchableType, VkQueue>::value ||
- std::is_same<DispatchableType, VkCommandBuffer>::value,
- "unrecognized dispatchable type");
+ static_assert(
+ std::is_same<DispatchableType, VkInstance>::value ||
+ std::is_same<DispatchableType, VkPhysicalDevice>::value ||
+ std::is_same<DispatchableType, VkDevice>::value ||
+ std::is_same<DispatchableType, InstanceDispatchable>::value ||
+ std::is_same<DispatchableType, VkQueue>::value ||
+ std::is_same<DispatchableType, VkCommandBuffer>::value ||
+ std::is_same<DispatchableType, DeviceDispatchable>::value,
+ "unrecognized dispatchable type");
}
template <typename DispatchableType>
@@ -170,6 +176,11 @@
return SetDataInternal(physical_dev, &data);
}
+inline bool SetData(InstanceDispatchable dispatchable,
+ const InstanceData& data) {
+ return SetDataInternal(dispatchable, &data);
+}
+
inline bool SetData(VkDevice dev, const DeviceData& data) {
return SetDataInternal(dev, &data);
}
@@ -182,6 +193,10 @@
return SetDataInternal(cmd, &data);
}
+inline bool SetData(DeviceDispatchable dispatchable, const DeviceData& data) {
+ return SetDataInternal(dispatchable, &data);
+}
+
inline InstanceData& GetData(VkInstance instance) {
return *reinterpret_cast<InstanceData*>(GetDataInternal(instance));
}
@@ -190,6 +205,10 @@
return *reinterpret_cast<InstanceData*>(GetDataInternal(physical_dev));
}
+inline InstanceData& GetData(InstanceDispatchable dispatchable) {
+ return *reinterpret_cast<InstanceData*>(GetDataInternal(dispatchable));
+}
+
inline DeviceData& GetData(VkDevice dev) {
return *reinterpret_cast<DeviceData*>(GetDataInternal(dev));
}
@@ -202,6 +221,10 @@
return *reinterpret_cast<DeviceData*>(GetDataInternal(cmd));
}
+inline DeviceData& GetData(DeviceDispatchable dispatchable) {
+ return *reinterpret_cast<DeviceData*>(GetDataInternal(dispatchable));
+}
+
} // namespace driver
} // namespace vulkan