1 /*
2  * Copyright 2015-2023 The Khronos Group Inc.
3  * Copyright 2015-2023 Valve Corporation
4  * Copyright 2015-2023 LunarG, Inc.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 #pragma once
9 
10 /* Need to define dispatch table
11  * Core struct can then have ptr to dispatch table at the top
12  * Along with object ptrs for current and next OBJ
13  */
14 
15 #include "vulkan_core.h"
16 
17 #define MAX_NUM_UNKNOWN_EXTS 250
18 
19  // Loader-Layer version negotiation API.  Versions add the following features:
20  //   Versions 0/1 - Initial.  Doesn't support vk_layerGetPhysicalDeviceProcAddr
21  //                  or vk_icdNegotiateLoaderLayerInterfaceVersion.
22  //   Version 2    - Add support for vk_layerGetPhysicalDeviceProcAddr and
23  //                  vk_icdNegotiateLoaderLayerInterfaceVersion.
24 #define CURRENT_LOADER_LAYER_INTERFACE_VERSION 2
25 #define MIN_SUPPORTED_LOADER_LAYER_INTERFACE_VERSION 1
26 
27 #define VK_CURRENT_CHAIN_VERSION 1
28 
29 // Typedef for use in the interfaces below
30 typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);
31 
32 // Version negotiation values
33 typedef enum VkNegotiateLayerStructType {
34     LAYER_NEGOTIATE_UNINTIALIZED = 0,
35     LAYER_NEGOTIATE_INTERFACE_STRUCT = 1,
36 } VkNegotiateLayerStructType;
37 
38 // Version negotiation structures
39 typedef struct VkNegotiateLayerInterface {
40     VkNegotiateLayerStructType sType;
41     void *pNext;
42     uint32_t loaderLayerInterfaceVersion;
43     PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr;
44     PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr;
45     PFN_GetPhysicalDeviceProcAddr pfnGetPhysicalDeviceProcAddr;
46 } VkNegotiateLayerInterface;
47 
48 // Version negotiation functions
49 typedef VkResult (VKAPI_PTR *PFN_vkNegotiateLoaderLayerInterfaceVersion)(VkNegotiateLayerInterface *pVersionStruct);
50 
51 // Function prototype for unknown physical device extension command
52 typedef VkResult(VKAPI_PTR *PFN_PhysDevExt)(VkPhysicalDevice phys_device);
53 
54 // ------------------------------------------------------------------------------------------------
55 // CreateInstance and CreateDevice support structures
56 
57 /* Sub type of structure for instance and device loader ext of CreateInfo.
58  * When sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
59  * or sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
60  * then VkLayerFunction indicates struct type pointed to by pNext
61  */
62 typedef enum VkLayerFunction_ {
63     VK_LAYER_LINK_INFO = 0,
64     VK_LOADER_DATA_CALLBACK = 1,
65     VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK = 2,
66     VK_LOADER_FEATURES = 3,
67 } VkLayerFunction;
68 
69 typedef struct VkLayerInstanceLink_ {
70     struct VkLayerInstanceLink_ *pNext;
71     PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
72     PFN_GetPhysicalDeviceProcAddr pfnNextGetPhysicalDeviceProcAddr;
73 } VkLayerInstanceLink;
74 
75 /*
76  * When creating the device chain the loader needs to pass
77  * down information about it's device structure needed at
78  * the end of the chain. Passing the data via the
79  * VkLayerDeviceInfo avoids issues with finding the
80  * exact instance being used.
81  */
82 typedef struct VkLayerDeviceInfo_ {
83     void *device_info;
84     PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
85 } VkLayerDeviceInfo;
86 
87 typedef VkResult (VKAPI_PTR *PFN_vkSetInstanceLoaderData)(VkInstance instance,
88         void *object);
89 typedef VkResult (VKAPI_PTR *PFN_vkSetDeviceLoaderData)(VkDevice device,
90         void *object);
91 typedef VkResult (VKAPI_PTR *PFN_vkLayerCreateDevice)(VkInstance instance, VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
92 						      const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, PFN_vkGetInstanceProcAddr layerGIPA, PFN_vkGetDeviceProcAddr *nextGDPA);
93 typedef void (VKAPI_PTR *PFN_vkLayerDestroyDevice)(VkDevice physicalDevice, const VkAllocationCallbacks *pAllocator, PFN_vkDestroyDevice destroyFunction);
94 
95 typedef enum VkLoaderFeastureFlagBits {
96     VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING = 0x00000001,
97 } VkLoaderFlagBits;
98 typedef VkFlags VkLoaderFeatureFlags;
99 
100 typedef struct {
101     VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
102     const void *pNext;
103     VkLayerFunction function;
104     union {
105         VkLayerInstanceLink *pLayerInfo;
106         PFN_vkSetInstanceLoaderData pfnSetInstanceLoaderData;
107         struct {
108 	        PFN_vkLayerCreateDevice pfnLayerCreateDevice;
109 	        PFN_vkLayerDestroyDevice pfnLayerDestroyDevice;
110 	    } layerDevice;
111         VkLoaderFeatureFlags loaderFeatures;
112     } u;
113 } VkLayerInstanceCreateInfo;
114 
115 typedef struct VkLayerDeviceLink_ {
116     struct VkLayerDeviceLink_ *pNext;
117     PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
118     PFN_vkGetDeviceProcAddr pfnNextGetDeviceProcAddr;
119 } VkLayerDeviceLink;
120 
121 typedef struct {
122     VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
123     const void *pNext;
124     VkLayerFunction function;
125     union {
126         VkLayerDeviceLink *pLayerInfo;
127         PFN_vkSetDeviceLoaderData pfnSetDeviceLoaderData;
128     } u;
129 } VkLayerDeviceCreateInfo;
130 
131 #ifdef __cplusplus
132 extern "C" {
133 #endif
134 
135 VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct);
136 
137 typedef enum VkChainType {
138     VK_CHAIN_TYPE_UNKNOWN = 0,
139     VK_CHAIN_TYPE_ENUMERATE_INSTANCE_EXTENSION_PROPERTIES = 1,
140     VK_CHAIN_TYPE_ENUMERATE_INSTANCE_LAYER_PROPERTIES = 2,
141     VK_CHAIN_TYPE_ENUMERATE_INSTANCE_VERSION = 3,
142 } VkChainType;
143 
144 typedef struct VkChainHeader {
145     VkChainType type;
146     uint32_t version;
147     uint32_t size;
148 } VkChainHeader;
149 
150 typedef struct VkEnumerateInstanceExtensionPropertiesChain {
151     VkChainHeader header;
152     VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceExtensionPropertiesChain *, const char *, uint32_t *,
153                                       VkExtensionProperties *);
154     const struct VkEnumerateInstanceExtensionPropertiesChain *pNextLink;
155 
156 #if defined(__cplusplus)
CallDownVkEnumerateInstanceExtensionPropertiesChain157     inline VkResult CallDown(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) const {
158         return pfnNextLayer(pNextLink, pLayerName, pPropertyCount, pProperties);
159     }
160 #endif
161 } VkEnumerateInstanceExtensionPropertiesChain;
162 
163 typedef struct VkEnumerateInstanceLayerPropertiesChain {
164     VkChainHeader header;
165     VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceLayerPropertiesChain *, uint32_t *, VkLayerProperties *);
166     const struct VkEnumerateInstanceLayerPropertiesChain *pNextLink;
167 
168 #if defined(__cplusplus)
CallDownVkEnumerateInstanceLayerPropertiesChain169     inline VkResult CallDown(uint32_t *pPropertyCount, VkLayerProperties *pProperties) const {
170         return pfnNextLayer(pNextLink, pPropertyCount, pProperties);
171     }
172 #endif
173 } VkEnumerateInstanceLayerPropertiesChain;
174 
175 typedef struct VkEnumerateInstanceVersionChain {
176     VkChainHeader header;
177     VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceVersionChain *, uint32_t *);
178     const struct VkEnumerateInstanceVersionChain *pNextLink;
179 
180 #if defined(__cplusplus)
CallDownVkEnumerateInstanceVersionChain181     inline VkResult CallDown(uint32_t *pApiVersion) const {
182         return pfnNextLayer(pNextLink, pApiVersion);
183     }
184 #endif
185 } VkEnumerateInstanceVersionChain;
186 
187 #ifdef __cplusplus
188 }
189 #endif
190