1 /*
2  * Copyright (c) 2015-2020 The Khronos Group Inc.
3  * Copyright (c) 2015-2020 Valve Corporation
4  * Copyright (c) 2015-2020 LunarG, Inc.
5  * Copyright (C) 2015-2020 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * Author: Arda Coskunses <arda@lunarg.com>
20  * Author: Tony Barbour <tony@LunarG.com>
21  * Author: Mark Lobodzinski <mark@lunarg.com>
22  */
23 #include <string.h>
24 #include <stdlib.h>
25 #include <cassert>
26 #include <mutex>
27 #include <unordered_map>
28 #include <vector>
29 
30 #include "vk_layer_data.h"
31 #include "vk_dispatch_table_helper.h"
32 #include "vk_layer_utils.h"
33 #include "vk_lunarg_device_profile_api_layer.h"
34 #include "vk_device_profile_api_layer.h"
35 
36 namespace device_profile_api {
37 
38 static std::mutex global_lock;
39 
40 static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
41 
42 struct layer_data {
43     VkInstance instance;
44     VkPhysicalDeviceProperties phy_device_props;
45     std::unordered_map<VkFormat, VkFormatProperties, std::hash<int> > format_properties_map;
46     VkPhysicalDeviceFeatures phy_device_features;
47     VkLayerInstanceDispatchTable dispatch_table;
48 };
49 
50 static std::unordered_map<void *, layer_data *> device_profile_api_dev_data_map;
51 
52 // device_profile_api Layer EXT APIs
53 typedef void(VKAPI_PTR *PFN_vkGetOriginalPhysicalDeviceLimitsEXT)(VkPhysicalDevice physicalDevice,
54                                                                   const VkPhysicalDeviceLimits *limits);
55 typedef void(VKAPI_PTR *PFN_vkSetPhysicalDeviceLimitsEXT)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceLimits *newLimits);
56 typedef void(VKAPI_PTR *PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT)(VkPhysicalDevice physicalDevice, VkFormat format,
57                                                                             const VkFormatProperties *properties);
58 typedef void(VKAPI_PTR *PFN_vkSetPhysicalDeviceFormatPropertiesEXT)(VkPhysicalDevice physicalDevice, VkFormat format,
59                                                                     const VkFormatProperties newProperties);
60 typedef void(VKAPI_PTR *PFN_vkGetOriginalPhysicalDeviceFormatProperties2EXT)(VkPhysicalDevice physicalDevice, VkFormat format,
61                                                                              const VkFormatProperties2 *properties);
62 typedef void(VKAPI_PTR *PFN_vkSetPhysicalDeviceFormatProperties2EXT)(VkPhysicalDevice physicalDevice, VkFormat format,
63                                                                      const VkFormatProperties2 newProperties);
64 typedef void(VKAPI_PTR *PFN_vkGetOriginalPhysicalDeviceFeaturesEXT)(VkPhysicalDevice physicalDevice,
65                                                                     const VkPhysicalDeviceFeatures *features);
66 typedef void(VKAPI_PTR *PFN_vkSetPhysicalDeviceFeaturesEXT)(VkPhysicalDevice physicalDevice, const VkFormatProperties2 newFeatures);
67 
GetOriginalPhysicalDeviceLimitsEXT(VkPhysicalDevice physicalDevice,VkPhysicalDeviceLimits * orgLimits)68 VKAPI_ATTR void VKAPI_CALL GetOriginalPhysicalDeviceLimitsEXT(VkPhysicalDevice physicalDevice, VkPhysicalDeviceLimits *orgLimits) {
69     std::lock_guard<std::mutex> lock(global_lock);
70     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
71     layer_data *instance_data = GetLayerDataPtr(phy_dev_data->instance, device_profile_api_dev_data_map);
72     VkPhysicalDeviceProperties props;
73     instance_data->dispatch_table.GetPhysicalDeviceProperties(physicalDevice, &props);
74     memcpy(orgLimits, &props.limits, sizeof(VkPhysicalDeviceLimits));
75 }
76 
SetPhysicalDeviceLimitsEXT(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceLimits * newLimits)77 VKAPI_ATTR void VKAPI_CALL SetPhysicalDeviceLimitsEXT(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceLimits *newLimits) {
78     std::lock_guard<std::mutex> lock(global_lock);
79     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
80     memcpy(&(phy_dev_data->phy_device_props.limits), newLimits, sizeof(VkPhysicalDeviceLimits));
81 }
82 
GetOriginalPhysicalDeviceFormatPropertiesEXT(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties * properties)83 VKAPI_ATTR void VKAPI_CALL GetOriginalPhysicalDeviceFormatPropertiesEXT(VkPhysicalDevice physicalDevice, VkFormat format,
84                                                                         VkFormatProperties *properties) {
85     std::lock_guard<std::mutex> lock(global_lock);
86     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
87     layer_data *instance_data = GetLayerDataPtr(phy_dev_data->instance, device_profile_api_dev_data_map);
88     instance_data->dispatch_table.GetPhysicalDeviceFormatProperties(physicalDevice, format, properties);
89 }
90 
SetPhysicalDeviceFormatPropertiesEXT(VkPhysicalDevice physicalDevice,VkFormat format,const VkFormatProperties newProperties)91 VKAPI_ATTR void VKAPI_CALL SetPhysicalDeviceFormatPropertiesEXT(VkPhysicalDevice physicalDevice, VkFormat format,
92                                                                 const VkFormatProperties newProperties) {
93     std::lock_guard<std::mutex> lock(global_lock);
94     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
95 
96     memcpy(&(phy_dev_data->format_properties_map[format]), &newProperties, sizeof(VkFormatProperties));
97 }
98 
GetOriginalPhysicalDeviceFormatProperties2EXT(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * properties)99 VKAPI_ATTR void VKAPI_CALL GetOriginalPhysicalDeviceFormatProperties2EXT(VkPhysicalDevice physicalDevice, VkFormat format,
100                                                                          VkFormatProperties2 *properties) {
101     // Currently only supports getting VkFormatProperties
102     // TODO: Add support for VkDrmFormatModifierPropertiesListEXT and future pNext structs of VkFormatProperties2
103     std::lock_guard<std::mutex> lock(global_lock);
104     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
105     layer_data *instance_data = GetLayerDataPtr(phy_dev_data->instance, device_profile_api_dev_data_map);
106     instance_data->dispatch_table.GetPhysicalDeviceFormatProperties2(physicalDevice, format, properties);
107 }
108 
SetPhysicalDeviceFormatProperties2EXT(VkPhysicalDevice physicalDevice,VkFormat format,const VkFormatProperties2 newProperties)109 VKAPI_ATTR void VKAPI_CALL SetPhysicalDeviceFormatProperties2EXT(VkPhysicalDevice physicalDevice, VkFormat format,
110                                                                  const VkFormatProperties2 newProperties) {
111     std::lock_guard<std::mutex> lock(global_lock);
112     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
113 
114     memcpy(&(phy_dev_data->format_properties_map[format]), &(newProperties.formatProperties), sizeof(VkFormatProperties));
115 }
116 
GetOriginalPhysicalDeviceFeaturesEXT(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures * features)117 VKAPI_ATTR void VKAPI_CALL GetOriginalPhysicalDeviceFeaturesEXT(VkPhysicalDevice physicalDevice,
118                                                                 VkPhysicalDeviceFeatures *features) {
119     std::lock_guard<std::mutex> lock(global_lock);
120     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
121     layer_data *instance_data = GetLayerDataPtr(phy_dev_data->instance, device_profile_api_dev_data_map);
122     instance_data->dispatch_table.GetPhysicalDeviceFeatures(physicalDevice, features);
123 }
124 
SetPhysicalDeviceFeaturesEXT(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceFeatures newFeatures)125 VKAPI_ATTR void VKAPI_CALL SetPhysicalDeviceFeaturesEXT(VkPhysicalDevice physicalDevice,
126                                                         const VkPhysicalDeviceFeatures newFeatures) {
127     std::lock_guard<std::mutex> lock(global_lock);
128     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
129 
130     memcpy(&phy_dev_data->phy_device_features, &newFeatures, sizeof(VkPhysicalDeviceFeatures));
131 }
132 
CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)133 VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
134                                               VkInstance *pInstance) {
135     VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
136     std::lock_guard<std::mutex> lock(global_lock);
137 
138     assert(chain_info->u.pLayerInfo);
139     PFN_vkGetInstanceProcAddr fp_get_instance_proc_addr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
140     PFN_vkCreateInstance fp_create_instance = (PFN_vkCreateInstance)fp_get_instance_proc_addr(NULL, "vkCreateInstance");
141     if (fp_create_instance == NULL) return VK_ERROR_INITIALIZATION_FAILED;
142 
143     // Advance the link info for the next element on the chain
144     chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
145 
146     VkResult result = fp_create_instance(pCreateInfo, pAllocator, pInstance);
147     if (result != VK_SUCCESS) return result;
148 
149     layer_data *instance_data = GetLayerDataPtr(*pInstance, device_profile_api_dev_data_map);
150     instance_data->instance = *pInstance;
151     layer_init_instance_dispatch_table(*pInstance, &instance_data->dispatch_table, fp_get_instance_proc_addr);
152     instance_data->dispatch_table.GetPhysicalDeviceProcAddr =
153         (PFN_GetPhysicalDeviceProcAddr)fp_get_instance_proc_addr(*pInstance, "vk_layerGetPhysicalDeviceProcAddr");
154 
155     uint32_t physical_device_count = 0;
156     instance_data->dispatch_table.EnumeratePhysicalDevices(*pInstance, &physical_device_count, NULL);
157 
158     std::vector<VkPhysicalDevice> physical_devices(physical_device_count);
159     result = instance_data->dispatch_table.EnumeratePhysicalDevices(*pInstance, &physical_device_count, physical_devices.data());
160     if (result != VK_SUCCESS) return result;
161 
162     for (VkPhysicalDevice physical_device : physical_devices) {
163         layer_data *phy_dev_data = GetLayerDataPtr(physical_device, device_profile_api_dev_data_map);
164         instance_data->dispatch_table.GetPhysicalDeviceProperties(physical_device, &phy_dev_data->phy_device_props);
165         instance_data->dispatch_table.GetPhysicalDeviceFeatures(physical_device, &phy_dev_data->phy_device_features);
166         phy_dev_data->instance = *pInstance;
167     }
168     return result;
169 }
170 
GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties * pProperties)171 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) {
172     std::lock_guard<std::mutex> lock(global_lock);
173     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
174     memcpy(pProperties, &phy_dev_data->phy_device_props, sizeof(VkPhysicalDeviceProperties));
175 }
176 
GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties * pProperties)177 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
178                                                              VkFormatProperties *pProperties) {
179     std::lock_guard<std::mutex> lock(global_lock);
180     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
181     layer_data *instance_data = GetLayerDataPtr(phy_dev_data->instance, device_profile_api_dev_data_map);
182     auto device_format_map_it = phy_dev_data->format_properties_map.find(format);
183     if (device_format_map_it != phy_dev_data->format_properties_map.end()) {
184         memcpy(pProperties, &phy_dev_data->format_properties_map[format], sizeof(VkFormatProperties));
185     } else {
186         instance_data->dispatch_table.GetPhysicalDeviceFormatProperties(physicalDevice, format, pProperties);
187     }
188 }
189 
GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pProperties)190 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
191                                                               VkFormatProperties2 *pProperties) {
192     std::lock_guard<std::mutex> lock(global_lock);
193     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
194     layer_data *instance_data = GetLayerDataPtr(phy_dev_data->instance, device_profile_api_dev_data_map);
195     auto device_format_map_it = phy_dev_data->format_properties_map.find(format);
196     if (device_format_map_it != phy_dev_data->format_properties_map.end()) {
197         memcpy((void *)&(pProperties->formatProperties), &phy_dev_data->format_properties_map[format], sizeof(VkFormatProperties));
198     } else {
199         instance_data->dispatch_table.GetPhysicalDeviceFormatProperties2(physicalDevice, format, pProperties);
200     }
201 }
202 
GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures * pFeatures)203 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) {
204     std::lock_guard<std::mutex> lock(global_lock);
205     layer_data *phy_dev_data = GetLayerDataPtr(physicalDevice, device_profile_api_dev_data_map);
206     memcpy(pFeatures, &phy_dev_data->phy_device_features, sizeof(VkPhysicalDeviceFeatures));
207 }
208 
209 static const VkLayerProperties device_profile_api_LayerProps = {
210     "VK_LAYER_LUNARG_device_profile_api",
211     VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION),  // specVersion
212     1,                                         // implementationVersion
213     "LunarG device profile api Layer",
214 };
215 
216 template <typename T>
EnumerateProperties(uint32_t src_count,const T * src_props,uint32_t * dst_count,T * dst_props)217 VkResult EnumerateProperties(uint32_t src_count, const T *src_props, uint32_t *dst_count, T *dst_props) {
218     if (!dst_props || !src_props) {
219         *dst_count = src_count;
220         return VK_SUCCESS;
221     }
222 
223     uint32_t copy_count = (*dst_count < src_count) ? *dst_count : src_count;
224     memcpy(dst_props, src_props, sizeof(T) * copy_count);
225     *dst_count = copy_count;
226 
227     return (copy_count == src_count) ? VK_SUCCESS : VK_INCOMPLETE;
228 }
229 
EnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)230 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
231     return EnumerateProperties(1, &device_profile_api_LayerProps, pCount, pProperties);
232 }
233 
EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)234 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
235                                                                     VkExtensionProperties *pProperties) {
236     if (pLayerName && !strcmp(pLayerName, device_profile_api_LayerProps.layerName))
237         return EnumerateProperties<VkExtensionProperties>(0, NULL, pCount, pProperties);
238 
239     return VK_ERROR_LAYER_NOT_PRESENT;
240 }
241 
GetPhysicalDeviceProcAddr(VkInstance instance,const char * name)242 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *name) {
243     if (!strcmp(name, "vkSetPhysicalDeviceLimitsEXT")) return (PFN_vkVoidFunction)SetPhysicalDeviceLimitsEXT;
244     if (!strcmp(name, "vkGetOriginalPhysicalDeviceLimitsEXT")) return (PFN_vkVoidFunction)GetOriginalPhysicalDeviceLimitsEXT;
245     if (!strcmp(name, "vkSetPhysicalDeviceFormatPropertiesEXT")) return (PFN_vkVoidFunction)SetPhysicalDeviceFormatPropertiesEXT;
246     if (!strcmp(name, "vkGetOriginalPhysicalDeviceFormatPropertiesEXT"))
247         return (PFN_vkVoidFunction)GetOriginalPhysicalDeviceFormatPropertiesEXT;
248     if (!strcmp(name, "vkSetPhysicalDeviceFormatProperties2EXT")) return (PFN_vkVoidFunction)SetPhysicalDeviceFormatProperties2EXT;
249     if (!strcmp(name, "vkGetOriginalPhysicalDeviceFormatProperties2EXT"))
250         return (PFN_vkVoidFunction)GetOriginalPhysicalDeviceFormatProperties2EXT;
251     if (!strcmp(name, "vkGetOriginalPhysicalDeviceFeaturesEXT")) return (PFN_vkVoidFunction)GetOriginalPhysicalDeviceFeaturesEXT;
252     if (!strcmp(name, "vkSetPhysicalDeviceFeaturesEXT")) return (PFN_vkVoidFunction)SetPhysicalDeviceFeaturesEXT;
253     layer_data *instance_data = GetLayerDataPtr(instance, device_profile_api_dev_data_map);
254     auto &table = instance_data->dispatch_table;
255     if (!table.GetPhysicalDeviceProcAddr) return nullptr;
256     return table.GetPhysicalDeviceProcAddr(instance, name);
257 }
258 
GetInstanceProcAddr(VkInstance instance,const char * name)259 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *name) {
260     if (!strcmp(name, "vkCreateInstance")) return (PFN_vkVoidFunction)CreateInstance;
261     if (!strcmp(name, "vkGetPhysicalDeviceProperties")) return (PFN_vkVoidFunction)GetPhysicalDeviceProperties;
262     if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties")) return (PFN_vkVoidFunction)GetPhysicalDeviceFormatProperties;
263     if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties2")) return (PFN_vkVoidFunction)GetPhysicalDeviceFormatProperties2;
264     if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties2KHR")) return (PFN_vkVoidFunction)GetPhysicalDeviceFormatProperties2;
265     if (!strcmp(name, "vkGetPhysicalDeviceFeatures")) return (PFN_vkVoidFunction)GetPhysicalDeviceFeatures;
266     if (!strcmp(name, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction)GetInstanceProcAddr;
267     if (!strcmp(name, "vkEnumerateInstanceExtensionProperties")) return (PFN_vkVoidFunction)EnumerateInstanceExtensionProperties;
268     if (!strcmp(name, "vkEnumerateInstanceLayerProperties")) return (PFN_vkVoidFunction)EnumerateInstanceLayerProperties;
269     if (!strcmp(name, "vkSetPhysicalDeviceLimitsEXT")) return (PFN_vkVoidFunction)SetPhysicalDeviceLimitsEXT;
270     if (!strcmp(name, "vkGetOriginalPhysicalDeviceLimitsEXT")) return (PFN_vkVoidFunction)GetOriginalPhysicalDeviceLimitsEXT;
271     if (!strcmp(name, "vkSetPhysicalDeviceFormatPropertiesEXT")) return (PFN_vkVoidFunction)SetPhysicalDeviceFormatPropertiesEXT;
272     if (!strcmp(name, "vkGetOriginalPhysicalDeviceFormatPropertiesEXT"))
273         return (PFN_vkVoidFunction)GetOriginalPhysicalDeviceFormatPropertiesEXT;
274     if (!strcmp(name, "vkSetPhysicalDeviceFormatProperties2EXT")) return (PFN_vkVoidFunction)SetPhysicalDeviceFormatProperties2EXT;
275     if (!strcmp(name, "vkGetOriginalPhysicalDeviceFormatProperties2EXT"))
276         return (PFN_vkVoidFunction)GetOriginalPhysicalDeviceFormatProperties2EXT;
277     if (!strcmp(name, "vkGetOriginalPhysicalDeviceFeaturesEXT")) return (PFN_vkVoidFunction)GetOriginalPhysicalDeviceFeaturesEXT;
278     if (!strcmp(name, "vkSetPhysicalDeviceFeaturesEXT")) return (PFN_vkVoidFunction)SetPhysicalDeviceFeaturesEXT;
279     assert(instance);
280     layer_data *instance_data = GetLayerDataPtr(instance, device_profile_api_dev_data_map);
281     auto &table = instance_data->dispatch_table;
282     if (!table.GetInstanceProcAddr) return nullptr;
283     return table.GetInstanceProcAddr(instance, name);
284 }
285 
286 }  // namespace device_profile_api
287 
vkEnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)288 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
289                                                                                   VkLayerProperties *pProperties) {
290     return device_profile_api::EnumerateInstanceLayerProperties(pCount, pProperties);
291 }
292 
vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)293 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
294                                                                                       VkExtensionProperties *pProperties) {
295     return device_profile_api::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
296 }
297 
vkGetInstanceProcAddr(VkInstance instance,const char * funcName)298 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
299     return device_profile_api::GetInstanceProcAddr(instance, funcName);
300 }
301 
vk_layerGetPhysicalDeviceProcAddr(VkInstance instance,const char * funcName)302 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance,
303                                                                                            const char *funcName) {
304     return device_profile_api::GetPhysicalDeviceProcAddr(instance, funcName);
305 }
306 
vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface * pVersionStruct)307 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct) {
308     assert(pVersionStruct != NULL);
309     assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT);
310 
311     // Fill in the function pointers if our version is at least capable of having the structure contain them.
312     if (pVersionStruct->loaderLayerInterfaceVersion >= 2) {
313         pVersionStruct->pfnGetInstanceProcAddr = vkGetInstanceProcAddr;
314         pVersionStruct->pfnGetDeviceProcAddr = nullptr;
315         pVersionStruct->pfnGetPhysicalDeviceProcAddr = vk_layerGetPhysicalDeviceProcAddr;
316     }
317 
318     if (pVersionStruct->loaderLayerInterfaceVersion < CURRENT_LOADER_LAYER_INTERFACE_VERSION) {
319         device_profile_api::loader_layer_if_version = pVersionStruct->loaderLayerInterfaceVersion;
320     } else if (pVersionStruct->loaderLayerInterfaceVersion > CURRENT_LOADER_LAYER_INTERFACE_VERSION) {
321         pVersionStruct->loaderLayerInterfaceVersion = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
322     }
323 
324     return VK_SUCCESS;
325 }
326