OSDN Git Service

vulkan: pass VK_LAYER_FUNCTION_DATA_CALLBACK to layers
authorChia-I Wu <olv@google.com>
Wed, 13 Apr 2016 02:20:59 +0000 (10:20 +0800)
committerChia-I Wu <olv@google.com>
Wed, 13 Apr 2016 20:48:45 +0000 (04:48 +0800)
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

vulkan/libvulkan/api.cpp
vulkan/libvulkan/driver.h

index 4e19af5..eeb32d4 100644 (file)
@@ -431,6 +431,11 @@ class LayerChain {
                               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 @@ class LayerChain {
     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 @@ bool LayerChain::Empty() const {
 
 void LayerChain::ModifyCreateInfo(VkInstanceCreateInfo& info) {
     if (layer_count_) {
-        const ActiveLayer& layer = layers_[0];
-
-        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);
-
-        // insert layer info
-        instance_chain_info_.pNext = info.pNext;
-        info.pNext = &instance_chain_info_;
+        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;
+
+        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;
+
+        info.pNext = &cb_info;
     }
 
     if (override_layers_.Count()) {
@@ -643,17 +649,19 @@ void LayerChain::ModifyCreateInfo(VkInstanceCreateInfo& info) {
 
 void LayerChain::ModifyCreateInfo(VkDeviceCreateInfo& info) {
     if (layer_count_) {
-        const ActiveLayer& layer = layers_[0];
-
-        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);
-
-        // insert layer info
-        device_chain_info_.pNext = info.pNext;
-        info.pNext = &device_chain_info_;
+        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;
+
+        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;
+
+        info.pNext = &cb_info;
     }
 
     if (override_layers_.Count()) {
@@ -890,6 +898,24 @@ void LayerChain::DestroyLayers(ActiveLayer* layers,
     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,
index 22db93f..5543792 100644 (file)
@@ -64,6 +64,9 @@ struct DeviceData {
 
 namespace driver {
 
+VK_DEFINE_HANDLE(InstanceDispatchable)
+VK_DEFINE_HANDLE(DeviceDispatchable)
+
 struct InstanceData {
     InstanceData(const VkAllocationCallbacks& alloc)
         : opaque_api_data(),
@@ -127,12 +130,15 @@ VKAPI_ATTR VkResult AllocateCommandBuffers(VkDevice device, const VkCommandBuffe
 
 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 @@ inline bool SetData(VkPhysicalDevice physical_dev, const InstanceData& data) {
     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 @@ inline bool SetData(VkCommandBuffer cmd, const DeviceData& data) {
     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 @@ inline InstanceData& GetData(VkPhysicalDevice physical_dev) {
     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 @@ inline DeviceData& GetData(VkCommandBuffer cmd) {
     return *reinterpret_cast<DeviceData*>(GetDataInternal(cmd));
 }
 
+inline DeviceData& GetData(DeviceDispatchable dispatchable) {
+    return *reinterpret_cast<DeviceData*>(GetDataInternal(dispatchable));
+}
+
 }  // namespace driver
 }  // namespace vulkan