blob: fc431b08ea0b236783d590fc95808f6de93ae8d1 [file] [log] [blame]
/*
*
* Copyright (C) 2015-2017 Valve Corporation
* Copyright (C) 2015-2017 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Author: Arda Coskunses <arda@lunarg.com>
* Author: Tony Barbour <tony@LunarG.com>
*/
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <unordered_map>
#include "vk_dispatch_table_helper.h"
#include "vk_lunarg_device_profile_api-layer.h"
#include "vk_device_profile_api_layer.h"
#include "threading.h"
namespace device_profile_api {
static std::unordered_map<dispatch_key, VkInstance> device_profile_api_instance_map;
static std::mutex global_lock;
// We keep physical device bookkeeping in this layer
// To keep track of modified and original profile values
uint32_t physical_device_count = 0;
VkPhysicalDevice *physical_devices = nullptr;
static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
// device_profile_api Layer data to store profiled GPU information
struct device_profile_api_data {
VkPhysicalDeviceProperties *props;
VkQueueFamilyProperties *queue_props;
VkDeviceQueueCreateInfo *queue_reqs;
VkPhysicalDeviceMemoryProperties memory_props;
VkPhysicalDeviceFeatures features;
uint32_t device_extension_count;
VkExtensionProperties *device_extensions;
};
static std::unordered_map<VkPhysicalDevice, struct device_profile_api_data> device_profile_api_dev_data_map;
static std::unordered_map<VkPhysicalDevice, struct device_profile_api_data> device_profile_api_dev_org_data_map;
// device_profile_api Layer EXT APIs
typedef VkResult(VKAPI_PTR *PFN_vkGetOriginalPhysicalDeviceLimitsEXT)(VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceLimits *limits);
static PFN_vkGetOriginalPhysicalDeviceLimitsEXT pfn_get_original_device_limits_extension;
typedef VkResult(VKAPI_PTR *PFN_vkSetPhysicalDeviceLimitsEXT)(VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceLimits *newLimits);
static PFN_vkSetPhysicalDeviceLimitsEXT pfn_set_physical_device_limits_extension;
VKAPI_ATTR void VKAPI_CALL GetOriginalPhysicalDeviceLimitsEXT(VkPhysicalDevice physicalDevice, VkPhysicalDeviceLimits *orgLimits) {
{
std::lock_guard<std::mutex> lock(global_lock);
// search if we got the device limits for this device and stored in device_profile_api layer
auto device_profile_api_data_it = device_profile_api_dev_org_data_map.find(physicalDevice);
// if we do not have it call getDeviceProperties implicitly and store device properties in the device_profile_api_layer
if (device_profile_api_data_it != device_profile_api_dev_org_data_map.end()) {
if (device_profile_api_dev_org_data_map[physicalDevice].props && orgLimits) {
memcpy( orgLimits, &(device_profile_api_dev_org_data_map[physicalDevice].props->limits), sizeof(VkPhysicalDeviceLimits));
}
}
}
}
VKAPI_ATTR VkResult VKAPI_CALL SetPhysicalDeviceLimitsEXT(VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceLimits *newLimits) {
{
std::lock_guard<std::mutex> lock(global_lock);
// search if we got the device limits for this device and stored in device_profile_api layer
auto device_profile_api_data_it = device_profile_api_dev_data_map.find(physicalDevice);
// if we do not have it call getDeviceProperties implicitly and store device properties in the device_profile_api_layer
if (device_profile_api_data_it != device_profile_api_dev_data_map.end()) {
if (device_profile_api_dev_data_map[physicalDevice].props && newLimits) {
memcpy(&(device_profile_api_dev_data_map[physicalDevice].props->limits), newLimits, sizeof(VkPhysicalDeviceLimits));
}
}
}
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
VkInstance *pInstance) {
VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
std::lock_guard<std::mutex> lock(global_lock);
assert(chain_info->u.pLayerInfo);
PFN_vkGetInstanceProcAddr fp_get_instance_proc_addr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
PFN_vkCreateInstance fp_create_instance = (PFN_vkCreateInstance)fp_get_instance_proc_addr(NULL, "vkCreateInstance");
if (fp_create_instance == NULL) return VK_ERROR_INITIALIZATION_FAILED;
// Advance the link info for the next element on the chain
chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
VkResult result = fp_create_instance(pCreateInfo, pAllocator, pInstance);
if (result != VK_SUCCESS) return result;
device_profile_api_instance_map[get_dispatch_key(*pInstance)] = *pInstance;
initInstanceTable(*pInstance, fp_get_instance_proc_addr);
layer_data *device_profile_data = GetLayerDataPtr(get_dispatch_key(*pInstance), layer_data_map);
device_profile_data->instance = *pInstance;
device_profile_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
layer_init_instance_dispatch_table(*pInstance, device_profile_data->instance_dispatch_table, fp_get_instance_proc_addr);
device_profile_data->instance_dispatch_table->EnumeratePhysicalDevices(*pInstance, &physical_device_count, NULL);
physical_devices = (VkPhysicalDevice *)malloc(sizeof(physical_devices[0]) * physical_device_count);
result = device_profile_data->instance_dispatch_table->EnumeratePhysicalDevices(*pInstance, &physical_device_count, physical_devices);
// Get original physical device props
for (uint8_t i = 0; i < physical_device_count; i++) {
auto device_profile_api_data_it = device_profile_api_dev_org_data_map.find(physical_devices[i]);
if (device_profile_api_data_it == device_profile_api_dev_org_data_map.end()) {
device_profile_api_dev_org_data_map[physical_devices[i]].props = (VkPhysicalDeviceProperties *)malloc(sizeof(VkPhysicalDeviceProperties));
if (device_profile_api_dev_org_data_map[physical_devices[i]].props) {
device_profile_data->instance_dispatch_table
->GetPhysicalDeviceProperties(physical_devices[i], device_profile_api_dev_org_data_map[physical_devices[i]].props);
} else {
if (i == 0) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
} else { // Free others
for (uint8_t j = 0; j < i; j++) {
if (device_profile_api_dev_org_data_map[physical_devices[j]].props) {
free(device_profile_api_dev_org_data_map[physical_devices[j]].props);
device_profile_api_dev_org_data_map[physical_devices[j]].props = nullptr;
}
}
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
}
}
}
// Store original props copy in profile as well
for (uint8_t i = 0; i < physical_device_count; i++) {
auto device_profile_api_data_it = device_profile_api_dev_data_map.find(physical_devices[i]);
if (device_profile_api_data_it == device_profile_api_dev_data_map.end()) {
device_profile_api_dev_data_map[physical_devices[i]].props = (VkPhysicalDeviceProperties *)malloc(sizeof(VkPhysicalDeviceProperties));
if (device_profile_api_dev_data_map[physical_devices[i]].props) {
memcpy( device_profile_api_dev_data_map[physical_devices[i]].props,
device_profile_api_dev_org_data_map[physical_devices[i]].props,
sizeof(VkPhysicalDeviceProperties));
} else {
if (i == 0) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
} else { // Free others
for (uint8_t j = 0; j < i; j++) {
if (device_profile_api_dev_data_map[physical_devices[j]].props) {
free(device_profile_api_dev_data_map[physical_devices[j]].props);
device_profile_api_dev_data_map[physical_devices[j]].props = nullptr;
}
}
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
}
}
}
return result;
}
VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
VkPhysicalDevice *pPhysicalDevices) {
VkResult result = instance_dispatch_table(instance)->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
return result;
}
VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
assert(chain_info->u.pLayerInfo);
PFN_vkGetInstanceProcAddr fp_get_instance_proc_addr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
PFN_vkGetDeviceProcAddr fp_get_device_proc_addr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
VkInstance instance = device_profile_api_instance_map[get_dispatch_key(physicalDevice)];
PFN_vkCreateDevice fp_create_device = (PFN_vkCreateDevice)fp_get_instance_proc_addr(instance, "vkCreateDevice");
if (fp_create_device == NULL) {
return VK_ERROR_INITIALIZATION_FAILED;
}
// Advance the link info for the next element on the chain
chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
VkResult result = fp_create_device(physicalDevice, pCreateInfo, pAllocator, pDevice);
if (result != VK_SUCCESS) {
return result;
}
initDeviceTable(*pDevice, fp_get_device_proc_addr);
pfn_get_original_device_limits_extension =
(PFN_vkGetOriginalPhysicalDeviceLimitsEXT)fp_get_device_proc_addr(*pDevice, "vkGetOriginalPhysicalDeviceLimitsEXT");
pfn_set_physical_device_limits_extension =
(PFN_vkSetPhysicalDeviceLimitsEXT)fp_get_device_proc_addr(*pDevice, "vkSetPhysicalDeviceLimitsEXT");
return result;
}
VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
dispatch_key key = get_dispatch_key(device);
device_dispatch_table(device)->DestroyDevice(device, pAllocator);
destroy_device_dispatch_table(key);
}
VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
dispatch_key key = get_dispatch_key(instance);
instance_dispatch_table(instance)->DestroyInstance(instance, pAllocator);
destroy_instance_dispatch_table(key);
device_profile_api_instance_map.erase(key);
}
VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) {
instance_dispatch_table(physicalDevice)->GetPhysicalDeviceFeatures(physicalDevice, pFeatures);
}
VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
VkFormatProperties *pFormatProperties) {
instance_dispatch_table(physicalDevice)->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
}
VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
VkImageType type, VkImageTiling tiling,
VkImageUsageFlags usage, VkImageCreateFlags flags,
VkImageFormatProperties *pImageFormatProperties) {
instance_dispatch_table(physicalDevice)
->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, pImageFormatProperties);
}
VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties *pProperties) {
{
std::lock_guard<std::mutex> lock(global_lock);
// Search if we got the device limits for this device and stored in device_profile_api layer
auto device_profile_api_data_it = device_profile_api_dev_data_map.find(physicalDevice);
if (device_profile_api_data_it != device_profile_api_dev_data_map.end()) {
// device_profile_api layer device limits exists for this device so overwrite with desired limits
if (device_profile_api_dev_data_map[physicalDevice].props) {
memcpy(pProperties, device_profile_api_dev_data_map[physicalDevice].props, sizeof(VkPhysicalDeviceProperties));
}
}
}
}
VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
uint32_t *pQueueFamilyPropertyCount,
VkQueueFamilyProperties *pQueueFamilyProperties) {
instance_dispatch_table(physicalDevice)
->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
}
VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
instance_dispatch_table(physicalDevice)->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
}
static const VkLayerProperties device_profile_api_LayerProps = {
"VK_LAYER_LUNARG_device_profile_api", VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION), // specVersion
1, // implementationVersion
"LunarG device profile api Layer",
};
static const VkExtensionProperties device_profile_api_physicaldevice_extensions[] = {{
"vkLayerdevice_profile_apiEXT", 1,
}};
template <typename T>
VkResult EnumerateProperties(uint32_t src_count, const T *src_props, uint32_t *dst_count, T *dst_props) {
if (!dst_props || !src_props) {
*dst_count = src_count;
return VK_SUCCESS;
}
uint32_t copy_count = (*dst_count < src_count) ? *dst_count : src_count;
memcpy(dst_props, src_props, sizeof(T) * copy_count);
*dst_count = copy_count;
return (copy_count == src_count) ? VK_SUCCESS : VK_INCOMPLETE;
}
VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
return EnumerateProperties(1, &device_profile_api_LayerProps, pCount, pProperties);
}
VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
VkLayerProperties *pProperties) {
return EnumerateProperties(1, &device_profile_api_LayerProps, pCount, pProperties);
}
VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
VkExtensionProperties *pProperties) {
if (pLayerName && !strcmp(pLayerName, device_profile_api_LayerProps.layerName))
return EnumerateProperties<VkExtensionProperties>(0, NULL, pCount, pProperties);
return VK_ERROR_LAYER_NOT_PRESENT;
}
VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
uint32_t *pCount, VkExtensionProperties *pProperties) {
if (pLayerName && !strcmp(pLayerName, device_profile_api_LayerProps.layerName)) {
uint32_t count = sizeof(device_profile_api_physicaldevice_extensions) / sizeof(device_profile_api_physicaldevice_extensions[0]);
return EnumerateProperties(count, device_profile_api_physicaldevice_extensions, pCount, pProperties);
}
return instance_dispatch_table(physicalDevice)->EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
}
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *name) {
if (!strcmp(name, "vkSetPhysicalDeviceLimitsEXT")) return (PFN_vkVoidFunction)SetPhysicalDeviceLimitsEXT;
if (!strcmp(name, "vkGetOriginalPhysicalDeviceLimitsEXT")) return (PFN_vkVoidFunction)GetOriginalPhysicalDeviceLimitsEXT;
if (instance_dispatch_table(instance)->GetPhysicalDeviceProcAddr == NULL) return NULL;
return instance_dispatch_table(instance)->GetPhysicalDeviceProcAddr(instance, name);
}
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *name) {
if (!strcmp(name, "vkGetDeviceProcAddr")) return (PFN_vkVoidFunction)GetDeviceProcAddr;
if (!strcmp(name, "vkDestroyDevice")) return (PFN_vkVoidFunction)DestroyDevice;
if (!strcmp(name, "vk_layerGetPhysicalDeviceProcAddr")) return (PFN_vkVoidFunction)GetPhysicalDeviceProcAddr;
if (device == NULL) return NULL;
if (device_dispatch_table(device)->GetDeviceProcAddr == NULL) return NULL;
return device_dispatch_table(device)->GetDeviceProcAddr(device, name);
}
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *name) {
if (!strcmp(name, "vkCreateInstance")) return (PFN_vkVoidFunction)CreateInstance;
if (!strcmp(name, "vkDestroyInstance")) return (PFN_vkVoidFunction)DestroyInstance;
if (!strcmp(name, "vkEnumeratePhysicalDevices")) return (PFN_vkVoidFunction)EnumeratePhysicalDevices;
if (!strcmp(name, "vk_layerGetPhysicalDeviceProcAddr")) return (PFN_vkVoidFunction)GetPhysicalDeviceProcAddr;
if (!strcmp(name, "vkGetPhysicalDeviceFeatures")) return (PFN_vkVoidFunction)GetPhysicalDeviceFeatures;
if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties")) return (PFN_vkVoidFunction)GetPhysicalDeviceFormatProperties;
if (!strcmp(name, "vkGetPhysicalDeviceImageFormatProperties")) return (PFN_vkVoidFunction)GetPhysicalDeviceImageFormatProperties;
if (!strcmp(name, "vkGetPhysicalDeviceProperties")) return (PFN_vkVoidFunction)GetPhysicalDeviceProperties;
if (!strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties")) return (PFN_vkVoidFunction)GetPhysicalDeviceQueueFamilyProperties;
if (!strcmp(name, "vkGetPhysicalDeviceMemoryProperties")) return (PFN_vkVoidFunction)GetPhysicalDeviceMemoryProperties;
if (!strcmp(name, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction)GetInstanceProcAddr;
if (!strcmp(name, "vkCreateDevice")) return (PFN_vkVoidFunction)CreateDevice;
if (!strcmp(name, "vkEnumerateInstanceExtensionProperties")) return (PFN_vkVoidFunction)EnumerateInstanceExtensionProperties;
if (!strcmp(name, "vkEnumerateInstanceLayerProperties")) return (PFN_vkVoidFunction)EnumerateInstanceLayerProperties;
if (!strcmp(name, "vkEnumerateDeviceLayerProperties")) return (PFN_vkVoidFunction)EnumerateDeviceLayerProperties;
if (!strcmp(name, "vkEnumerateDeviceExtensionProperties")) return (PFN_vkVoidFunction)EnumerateDeviceExtensionProperties;
if (!strcmp(name, "vkSetPhysicalDeviceLimitsEXT")) return (PFN_vkVoidFunction)SetPhysicalDeviceLimitsEXT;
if (!strcmp(name, "vkGetOriginalPhysicalDeviceLimitsEXT")) return (PFN_vkVoidFunction)GetOriginalPhysicalDeviceLimitsEXT;
assert(instance);
PFN_vkVoidFunction proc = GetDeviceProcAddr(VK_NULL_HANDLE, name);
if (proc) return proc;
if (instance_dispatch_table(instance)->GetInstanceProcAddr == NULL) return NULL;
return instance_dispatch_table(instance)->GetInstanceProcAddr(instance, name);
}
} // namespace device_profile_api
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
VkLayerProperties *pProperties) {
return device_profile_api::EnumerateInstanceLayerProperties(pCount, pProperties);
}
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
VkLayerProperties *pProperties) {
assert(physicalDevice == VK_NULL_HANDLE);
return device_profile_api::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
}
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
VkExtensionProperties *pProperties) {
return device_profile_api::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
}
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
const char *pLayerName, uint32_t *pCount,
VkExtensionProperties *pProperties) {
assert(physicalDevice == VK_NULL_HANDLE);
return device_profile_api::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
return device_profile_api::GetDeviceProcAddr(dev, funcName);
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
return device_profile_api::GetInstanceProcAddr(instance, funcName);
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance,
const char *funcName) {
return device_profile_api::GetPhysicalDeviceProcAddr(instance, funcName);
}
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct) {
assert(pVersionStruct != NULL);
assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT);
// Fill in the function pointers if our version is at least capable of having the structure contain them.
if (pVersionStruct->loaderLayerInterfaceVersion >= 2) {
pVersionStruct->pfnGetInstanceProcAddr = vkGetInstanceProcAddr;
pVersionStruct->pfnGetDeviceProcAddr = vkGetDeviceProcAddr;
pVersionStruct->pfnGetPhysicalDeviceProcAddr = vk_layerGetPhysicalDeviceProcAddr;
}
if (pVersionStruct->loaderLayerInterfaceVersion < CURRENT_LOADER_LAYER_INTERFACE_VERSION) {
device_profile_api::loader_layer_if_version = pVersionStruct->loaderLayerInterfaceVersion;
} else if (pVersionStruct->loaderLayerInterfaceVersion > CURRENT_LOADER_LAYER_INTERFACE_VERSION) {
pVersionStruct->loaderLayerInterfaceVersion = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
}
return VK_SUCCESS;
}