loader: Add instance callback to set dispatchable objects
authorJon Ashburn <jon@lunarg.com>
Tue, 29 Mar 2016 17:16:01 +0000 (11:16 -0600)
committerJon Ashburn <jon@lunarg.com>
Fri, 1 Apr 2016 16:47:17 +0000 (10:47 -0600)
Change-Id: I73b8b6edfee491c53216b730c99a7ea34ade3b4e

include/vulkan/vk_layer.h
loader/loader.c

index 2a45800..8538eec 100644 (file)
@@ -261,9 +261,15 @@ typedef enum VkLayerDbgAction_ {
 // ------------------------------------------------------------------------------------------------
 // CreateInstance and CreateDevice support structures
 
+/* Sub type of structure for instance and device loader ext of CreateInfo.
+ * When sType == VK_STRUCTURE_TYPE_LAYER_INSTANCE_CREATE_INFO
+ * or sType == VK_STRUCTURE_TYPE_LAYER_DEVICE_CREATE_INFO
+ * then VkLayerFunction indicates struct type pointed to by pNext
+ */
 typedef enum VkLayerFunction_ {
     VK_LAYER_LINK_INFO = 0,
-    VK_LAYER_DEVICE_INFO = 1
+    VK_LAYER_DEVICE_INFO = 1,
+    VK_LOADER_DISPATCH_CALLBACK = 2
 } VkLayerFunction;
 
 typedef struct VkLayerInstanceLink_ {
@@ -283,12 +289,16 @@ typedef struct VkLayerDeviceInfo_ {
     PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
 } VkLayerDeviceInfo;
 
+typedef VkResult (VKAPI_PTR *PFN_vkSetInstanceLoaderData)(VkInstance instance,
+        void *object);
+
 typedef struct {
     VkStructureType sType; // VK_STRUCTURE_TYPE_LAYER_INSTANCE_CREATE_INFO
     const void *pNext;
     VkLayerFunction function;
     union {
         VkLayerInstanceLink *pLayerInfo;
+        PFN_vkSetInstanceLoaderData pfnSetInstanceLoaderData;
     } u;
 } VkLayerInstanceCreateInfo;
 
index 5a00b6f..fd2d1fe 100644 (file)
@@ -261,6 +261,16 @@ void loader_log(const struct loader_instance *inst, VkFlags msg_type,
     fputc('\n', stderr);
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL vkSetInstanceDispatch(VkInstance instance, void *object) {
+
+    struct loader_instance *inst = loader_get_instance(instance);
+    if (!inst) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+    loader_set_dispatch(object, inst->disp);
+    return VK_SUCCESS;
+}
+
 #if defined(WIN32)
 static char *loader_get_next_path(char *path);
 /**
@@ -3267,6 +3277,16 @@ VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo,
     PFN_vkCreateInstance fpCreateInstance =
         (PFN_vkCreateInstance)nextGIPA(*created_instance, "vkCreateInstance");
     if (fpCreateInstance) {
+        VkLayerInstanceCreateInfo create_info_disp;
+
+        create_info_disp.sType =
+            VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+        create_info_disp.function = VK_LOADER_DISPATCH_CALLBACK;
+
+        create_info_disp.u.pfnSetInstanceLoaderData = vkSetInstanceDispatch;
+
+        create_info_disp.pNext = loader_create_info.pNext;
+        loader_create_info.pNext = &create_info_disp;
         res =
             fpCreateInstance(&loader_create_info, pAllocator, created_instance);
     } else {