diff options
| author | Mark Young <marky@lunarg.com> | 2017-01-19 21:10:49 -0700 |
|---|---|---|
| committer | Lenny Komow <lenny@lunarg.com> | 2017-01-24 14:07:22 -0700 |
| commit | 82ea0b0103880d011ca679b14f0fc5542c5b2012 (patch) | |
| tree | 11be85261197447e58e046affecbd43c36b4a8d8 /layers | |
| parent | 8fc3d170de6515c0d26fb6b17bd3b5e27711e607 (diff) | |
| download | usermoji-82ea0b0103880d011ca679b14f0fc5542c5b2012.tar.xz | |
loader: Update the loader to 1.0.39
Add new extensions for 1.0.39. Also, updated layers to include
minimal set of functionality for 1.0.39 extensions. Extensions include:
- VK_KHR_get_physical_device_properties2
- VK_KHR_shader_draw_parameters
- VK_EXT_direct_mode_display
- VK_EXT_display_surface_counter
- VK_EXT_display_control
Also, redo the LoaderAndLayerIf document.
Change-Id: I10412086da7a798afe832a3892e18f606259b5af
Diffstat (limited to 'layers')
25 files changed, 1279 insertions, 133 deletions
diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt index d3addc9f..52d13a7e 100644 --- a/layers/CMakeLists.txt +++ b/layers/CMakeLists.txt @@ -11,7 +11,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") endif() if (BUILD_WSI_XLIB_SUPPORT) - add_definitions(-DVK_USE_PLATFORM_XLIB_KHR) + add_definitions(-DVK_USE_PLATFORM_XLIB_KHR -DVK_USE_PLATFORM_XLIB_XRANDR_EXT) endif() if (BUILD_WSI_WAYLAND_SUPPORT) diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index fd21f013..b6b9c821 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -117,6 +117,8 @@ struct instance_layer_data { CALL_STATE vkEnumeratePhysicalDevicesState = UNCALLED; uint32_t physical_devices_count = 0; + CALL_STATE vkEnumeratePhysicalDeviceGroupsState = UNCALLED; + uint32_t physical_device_groups_count = 0; CHECK_DISABLED disabled = {}; unordered_map<VkPhysicalDevice, PHYSICAL_DEVICE_STATE> physical_device_map; @@ -182,6 +184,8 @@ struct layer_data { static unordered_map<void *, layer_data *> layer_data_map; static unordered_map<void *, instance_layer_data *> instance_layer_data_map; +static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION; + static const VkLayerProperties global_layer = { "VK_LAYER_LUNARG_core_validation", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer", }; @@ -4103,7 +4107,6 @@ CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallba instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(*pInstance), instance_layer_data_map); instance_data->instance = *pInstance; layer_init_instance_dispatch_table(*pInstance, &instance_data->dispatch_table, fpGetInstanceProcAddr); - instance_data->report_data = debug_report_create_instance( &instance_data->dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames); checkInstanceRegisterExtensions(pCreateInfo, instance_data); @@ -12941,6 +12944,9 @@ intercept_khr_swapchain_command(const char *name, VkDevice dev); static PFN_vkVoidFunction intercept_khr_surface_command(const char *name, VkInstance instance); +static PFN_vkVoidFunction +intercept_extension_instance_commands(const char *name, VkInstance instance); + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice dev, const char *funcName) { PFN_vkVoidFunction proc = intercept_core_device_command(funcName); if (proc) @@ -12978,12 +12984,27 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance if (proc) return proc; + proc = intercept_extension_instance_commands(funcName, instance); + if (proc) + return proc; + auto &table = instance_data->dispatch_table; if (!table.GetInstanceProcAddr) return nullptr; return table.GetInstanceProcAddr(instance, funcName); } +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + assert(instance); + + instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map); + + auto &table = instance_data->dispatch_table; + if (!table.GetPhysicalDeviceProcAddr) + return nullptr; + return table.GetPhysicalDeviceProcAddr(instance, funcName); +} + static PFN_vkVoidFunction intercept_core_instance_command(const char *name) { static const struct { @@ -12991,6 +13012,7 @@ intercept_core_instance_command(const char *name) { PFN_vkVoidFunction proc; } core_instance_commands[] = { { "vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr) }, + { "vk_layerGetPhysicalDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProcAddr) }, { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) }, { "vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance) }, { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) }, @@ -13240,6 +13262,11 @@ intercept_khr_surface_command(const char *name, VkInstance instance) { return nullptr; } +static PFN_vkVoidFunction +intercept_extension_instance_commands(const char *name, VkInstance instance) { + return NULL; +} + } // namespace core_validation // vk_layer_logging.h expects these to be defined @@ -13297,3 +13324,28 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { return core_validation::GetInstanceProcAddr(instance, funcName); } + +VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + return core_validation::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) { + core_validation::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; +} + diff --git a/layers/image.cpp b/layers/image.cpp index fd4e1338..bba0ffd3 100644 --- a/layers/image.cpp +++ b/layers/image.cpp @@ -72,6 +72,8 @@ struct layer_data { physicalDeviceProperties(){}; }; +static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION; + static unordered_map<void *, layer_data *> layer_data_map; static std::mutex global_lock; @@ -136,7 +138,6 @@ CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallba my_data->instance = *pInstance; my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); - my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames); @@ -1319,6 +1320,17 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance return pTable->GetInstanceProcAddr(instance, funcName); } +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + assert(instance); + + layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + + VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; + if (pTable->GetPhysicalDeviceProcAddr == NULL) + return NULL; + return pTable->GetPhysicalDeviceProcAddr(instance, funcName); +} + static PFN_vkVoidFunction intercept_core_instance_command(const char *name) { static const struct { @@ -1334,6 +1346,7 @@ intercept_core_instance_command(const char *name) { { "vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties) }, { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) }, { "vkGetPhysicalDeviceProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProperties) }, + { "vk_layerGetPhysicalDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProcAddr) }, }; for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) { @@ -1432,3 +1445,27 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { return image::GetInstanceProcAddr(instance, funcName); } + +VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + return image::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) { + image::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; +} diff --git a/layers/linux/VkLayer_core_validation.json b/layers/linux/VkLayer_core_validation.json index 31c48c00..7fb94d2d 100644 --- a/layers/linux/VkLayer_core_validation.json +++ b/layers/linux/VkLayer_core_validation.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_LUNARG_core_validation", "type": "GLOBAL", "library_path": "./libVkLayer_core_validation.so", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "LunarG Validation Layer", "instance_extensions": [ diff --git a/layers/linux/VkLayer_image.json b/layers/linux/VkLayer_image.json index 97df7916..39dd4e63 100644 --- a/layers/linux/VkLayer_image.json +++ b/layers/linux/VkLayer_image.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_LUNARG_image", "type": "GLOBAL", "library_path": "./libVkLayer_image.so", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "LunarG Validation Layer", "instance_extensions": [ diff --git a/layers/linux/VkLayer_object_tracker.json b/layers/linux/VkLayer_object_tracker.json index c48afdfe..95bf2801 100644 --- a/layers/linux/VkLayer_object_tracker.json +++ b/layers/linux/VkLayer_object_tracker.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_LUNARG_object_tracker", "type": "GLOBAL", "library_path": "./libVkLayer_object_tracker.so", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "LunarG Validation Layer", "instance_extensions": [ diff --git a/layers/linux/VkLayer_parameter_validation.json b/layers/linux/VkLayer_parameter_validation.json index a9abaa39..d679e665 100644 --- a/layers/linux/VkLayer_parameter_validation.json +++ b/layers/linux/VkLayer_parameter_validation.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_LUNARG_parameter_validation", "type": "GLOBAL", "library_path": "./libVkLayer_parameter_validation.so", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "LunarG Validation Layer", "instance_extensions": [ diff --git a/layers/linux/VkLayer_swapchain.json b/layers/linux/VkLayer_swapchain.json index 6a2691e6..f9feb062 100644 --- a/layers/linux/VkLayer_swapchain.json +++ b/layers/linux/VkLayer_swapchain.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_LUNARG_swapchain", "type": "GLOBAL", "library_path": "./libVkLayer_swapchain.so", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "LunarG Validation Layer", "instance_extensions": [ diff --git a/layers/linux/VkLayer_threading.json b/layers/linux/VkLayer_threading.json index 2d87cc1e..2b0a3a38 100644 --- a/layers/linux/VkLayer_threading.json +++ b/layers/linux/VkLayer_threading.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_GOOGLE_threading", "type": "GLOBAL", "library_path": "./libVkLayer_threading.so", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "Google Validation Layer", "instance_extensions": [ diff --git a/layers/linux/VkLayer_unique_objects.json b/layers/linux/VkLayer_unique_objects.json index b9a87d59..a5f7a6f8 100644 --- a/layers/linux/VkLayer_unique_objects.json +++ b/layers/linux/VkLayer_unique_objects.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_GOOGLE_unique_objects", "type": "GLOBAL", "library_path": "./libVkLayer_unique_objects.so", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "Google Validation Layer" } diff --git a/layers/object_tracker.cpp b/layers/object_tracker.cpp index 00d19f31..fb3354ba 100644 --- a/layers/object_tracker.cpp +++ b/layers/object_tracker.cpp @@ -46,6 +46,8 @@ namespace object_tracker { +static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION; + static void InitObjectTracker(layer_data *my_data, const VkAllocationCallbacks *pAllocator) { layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_object_tracker"); @@ -573,6 +575,8 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *pName); +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName); + VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); @@ -3150,6 +3154,8 @@ static void CheckDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, device_data->wsi_display_swapchain_enabled = false; device_data->wsi_display_extension_enabled = false; device_data->objtrack_extensions_enabled = false; + device_data->nvx_device_generated_commands_enabled = false; + device_data->ext_display_control_enabled = false; for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) { @@ -3164,12 +3170,17 @@ static void CheckDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0) { device_data->objtrack_extensions_enabled = true; } + if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME) == 0) { + device_data->nvx_device_generated_commands_enabled = true; + } + if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME) == 0) { + device_data->ext_display_control_enabled = true; + } } } static void CheckInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) { VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(ot_instance_table_map, instance); - instanceExtMap[pDisp] = {}; @@ -3979,6 +3990,405 @@ VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCountAMD(VkCommandBuffer comman } } +// VK_KHR_get_physical_device_properties2 Extension +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR *pFeatures) { + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (!skip) { + get_dispatch_table(ot_instance_table_map, physicalDevice)->GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures); + } +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2KHR *pProperties) { + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (!skip) { + get_dispatch_table(ot_instance_table_map, physicalDevice)->GetPhysicalDeviceProperties2KHR(physicalDevice, pProperties); + } +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format, + VkFormatProperties2KHR *pFormatProperties) { + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (!skip) { + get_dispatch_table(ot_instance_table_map, physicalDevice) + ->GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, pFormatProperties); + } +} + +VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties2KHR( + VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo, + VkImageFormatProperties2KHR *pImageFormatProperties) { + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (skip) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + result = get_dispatch_table(ot_instance_table_map, physicalDevice) + ->GetPhysicalDeviceImageFormatProperties2KHR(physicalDevice, pImageFormatInfo, pImageFormatProperties); + + return result; +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice, + uint32_t *pQueueFamilyPropertyCount, + VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (!skip) { + get_dispatch_table(ot_instance_table_map, physicalDevice) + ->GetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties); + } +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties2KHR(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties) { + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (!skip) { + get_dispatch_table(ot_instance_table_map, physicalDevice) + ->GetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties); + } +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties2KHR( + VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount, + VkSparseImageFormatProperties2KHR *pProperties) { + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (!skip) { + get_dispatch_table(ot_instance_table_map, physicalDevice) + ->GetPhysicalDeviceSparseImageFormatProperties2KHR(physicalDevice, pFormatInfo, pPropertyCount, pProperties); + } +} + +// VK_NVX_device_generated_commands Extension +VKAPI_ATTR void VKAPI_CALL CmdProcessCommandsNVX(VkCommandBuffer commandBuffer, + const VkCmdProcessCommandsInfoNVX *pProcessCommandsInfo) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false, + VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); + if (!skip_call && dev_data->dispatch_table.CmdProcessCommandsNVX) { + dev_data->dispatch_table.CmdProcessCommandsNVX(commandBuffer, pProcessCommandsInfo); + } +} + +VKAPI_ATTR void VKAPI_CALL CmdReserveSpaceForCommandsNVX(VkCommandBuffer commandBuffer, + const VkCmdReserveSpaceForCommandsInfoNVX *pReserveSpaceInfo) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false, + VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); + if (!skip_call && dev_data->dispatch_table.CmdReserveSpaceForCommandsNVX) { + dev_data->dispatch_table.CmdReserveSpaceForCommandsNVX(commandBuffer, pReserveSpaceInfo); + } +} + +VKAPI_ATTR VkResult VKAPI_CALL CreateIndirectCommandsLayoutNVX(VkDevice device, + const VkIndirectCommandsLayoutCreateInfoNVX *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkIndirectCommandsLayoutNVX *pIndirectCommandsLayout) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + if (skip_call) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkResult result = VK_SUCCESS; + if (dev_data->dispatch_table.CreateIndirectCommandsLayoutNVX) { + result = dev_data->dispatch_table.CreateIndirectCommandsLayoutNVX(device, pCreateInfo, pAllocator, pIndirectCommandsLayout); + } + return result; +} + +VKAPI_ATTR void VKAPI_CALL DestroyIndirectCommandsLayoutNVX(VkDevice device, VkIndirectCommandsLayoutNVX indirectCommandsLayout, + const VkAllocationCallbacks *pAllocator) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + if (!skip_call) { + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + if (dev_data->dispatch_table.DestroyIndirectCommandsLayoutNVX) { + dev_data->dispatch_table.DestroyIndirectCommandsLayoutNVX(device, indirectCommandsLayout, pAllocator); + } + } +} + +VKAPI_ATTR VkResult VKAPI_CALL CreateObjectTableNVX(VkDevice device, const VkObjectTableCreateInfoNVX *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkObjectTableNVX *pObjectTable) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + if (skip_call) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkResult result = VK_SUCCESS; + if (dev_data->dispatch_table.CreateObjectTableNVX) { + result = dev_data->dispatch_table.CreateObjectTableNVX(device, pCreateInfo, pAllocator, pObjectTable); + } + return result; +} + +VKAPI_ATTR void VKAPI_CALL DestroyObjectTableNVX(VkDevice device, VkObjectTableNVX objectTable, + const VkAllocationCallbacks *pAllocator) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + if (!skip_call) { + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + if (dev_data->dispatch_table.DestroyObjectTableNVX) { + dev_data->dispatch_table.DestroyObjectTableNVX(device, objectTable, pAllocator); + } + } +} + +VKAPI_ATTR VkResult VKAPI_CALL RegisterObjectsNVX(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, + const VkObjectTableEntryNVX *const *ppObjectTableEntries, + const uint32_t *pObjectIndices) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + if (skip_call) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkResult result = VK_SUCCESS; + if (dev_data->dispatch_table.RegisterObjectsNVX) { + result = + dev_data->dispatch_table.RegisterObjectsNVX(device, objectTable, objectCount, ppObjectTableEntries, pObjectIndices); + } + return result; +} + +VKAPI_ATTR VkResult VKAPI_CALL UnregisterObjectsNVX(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, + const VkObjectEntryTypeNVX *pObjectEntryTypes, const uint32_t *pObjectIndices) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + if (skip_call) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkResult result = VK_SUCCESS; + if (dev_data->dispatch_table.UnregisterObjectsNVX) { + result = dev_data->dispatch_table.UnregisterObjectsNVX(device, objectTable, objectCount, pObjectEntryTypes, pObjectIndices); + } + return result; +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceGeneratedCommandsPropertiesNVX(VkPhysicalDevice physicalDevice, + VkDeviceGeneratedCommandsFeaturesNVX *pFeatures, + VkDeviceGeneratedCommandsLimitsNVX *pLimits) { + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (skip) { + get_dispatch_table(ot_instance_table_map, physicalDevice) + ->GetPhysicalDeviceGeneratedCommandsPropertiesNVX(physicalDevice, pFeatures, pLimits); + } +} + +// VK_EXT_direct_mode_display Extension +VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) { + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (skip) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + result = get_dispatch_table(ot_instance_table_map, physicalDevice)->ReleaseDisplayEXT(physicalDevice, display); + + return result; +} + +// VK_EXT_acquire_xlib_display Extension +#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT +VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, VkDisplayKHR display) { + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (skip) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + result = get_dispatch_table(ot_instance_table_map, physicalDevice)->AcquireXlibDisplayEXT(physicalDevice, dpy, display); + + return result; +} + +VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput, + VkDisplayKHR *pDisplay) { + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (skip) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + result = get_dispatch_table(ot_instance_table_map, physicalDevice) + ->GetRandROutputDisplayEXT(physicalDevice, dpy, rrOutput, pDisplay); + if (result == VK_SUCCESS && pDisplay != NULL) { + std::lock_guard<std::mutex> lock(global_lock); + CreateObject(physicalDevice, pDisplay, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT, nullptr); + } + + return result; +} +#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT + +// VK_EXT_display_surface_counter Extension +VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, + VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + bool skip = false; + { + std::unique_lock<std::mutex> lock(global_lock); + skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false, + VALIDATION_ERROR_UNDEFINED); + } + if (skip) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + result = get_dispatch_table(ot_instance_table_map, physicalDevice) + ->GetPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, pSurfaceCapabilities); + + return result; +} + +// VK_EXT_display_control Extension +VKAPI_ATTR VkResult VKAPI_CALL DisplayPowerControlEXT(VkDevice device, VkDisplayKHR display, + const VkDisplayPowerInfoEXT *pDisplayPowerInfo) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + if (skip_call) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkResult result = VK_SUCCESS; + if (dev_data->dispatch_table.DisplayPowerControlEXT) { + result = dev_data->dispatch_table.DisplayPowerControlEXT(device, display, pDisplayPowerInfo); + } + return result; +} + +VKAPI_ATTR VkResult VKAPI_CALL RegisterDeviceEventEXT(VkDevice device, const VkDeviceEventInfoEXT *pDeviceEventInfo, + const VkAllocationCallbacks *pAllocator, VkFence *pFence) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + if (skip_call) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkResult result = VK_SUCCESS; + if (dev_data->dispatch_table.RegisterDeviceEventEXT) { + result = dev_data->dispatch_table.RegisterDeviceEventEXT(device, pDeviceEventInfo, pAllocator, pFence); + if (result == VK_SUCCESS && pFence != NULL) { + std::lock_guard<std::mutex> lock(global_lock); + CreateObject(device, *pFence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, pAllocator); + } + } + return result; +} + +VKAPI_ATTR VkResult VKAPI_CALL RegisterDisplayEventEXT(VkDevice device, VkDisplayKHR display, + const VkDisplayEventInfoEXT *pDisplayEventInfo, + const VkAllocationCallbacks *pAllocator, VkFence *pFence) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + if (skip_call) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkResult result = VK_SUCCESS; + if (dev_data->dispatch_table.RegisterDisplayEventEXT) { + result = dev_data->dispatch_table.RegisterDisplayEventEXT(device, display, pDisplayEventInfo, pAllocator, pFence); + if (result == VK_SUCCESS && pFence != NULL) { + std::lock_guard<std::mutex> lock(global_lock); + CreateObject(device, *pFence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, pAllocator); + } + } + return result; +} + +VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainCounterEXT(VkDevice device, VkSwapchainKHR swapchain, + VkSurfaceCounterFlagBitsEXT counter, uint64_t *pCounterValue) { + bool skip_call = VK_FALSE; + std::unique_lock<std::mutex> lock(global_lock); + skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_UNDEFINED); + lock.unlock(); + if (skip_call) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkResult result = VK_SUCCESS; + if (dev_data->dispatch_table.GetSwapchainCounterEXT) { + result = dev_data->dispatch_table.GetSwapchainCounterEXT(device, swapchain, counter, pCounterValue); + } + return result; +} static inline PFN_vkVoidFunction InterceptCoreDeviceCommand(const char *name) { if (!name || name[0] != 'v' || name[1] != 'k') @@ -4248,6 +4658,7 @@ static inline PFN_vkVoidFunction InterceptCoreDeviceCommand(const char *name) { return NULL; } + static inline PFN_vkVoidFunction InterceptCoreInstanceCommand(const char *name) { if (!name || name[0] != 'v' || name[1] != 'k') return NULL; @@ -4259,6 +4670,8 @@ static inline PFN_vkVoidFunction InterceptCoreInstanceCommand(const char *name) return (PFN_vkVoidFunction)DestroyInstance; if (!strcmp(name, "EnumeratePhysicalDevices")) return (PFN_vkVoidFunction)EnumeratePhysicalDevices; + if (!strcmp(name, "_layerGetPhysicalDeviceProcAddr")) + return (PFN_vkVoidFunction)GetPhysicalDeviceProcAddr; if (!strcmp(name, "GetPhysicalDeviceFeatures")) return (PFN_vkVoidFunction)GetPhysicalDeviceFeatures; if (!strcmp(name, "GetPhysicalDeviceFormatProperties")) @@ -4289,6 +4702,89 @@ static inline PFN_vkVoidFunction InterceptCoreInstanceCommand(const char *name) return NULL; } +static inline PFN_vkVoidFunction InterceptDeviceExtensionCommand(const char *name, VkDevice device) { + if (device) { + layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + + if (!name || name[0] != 'v' || name[1] != 'k') + return NULL; + + name += 2; + + if (device_data->nvx_device_generated_commands_enabled) { + if (!strcmp(name, "CmdProcessCommandsNVX")) + return (PFN_vkVoidFunction)CmdProcessCommandsNVX; + if (!strcmp(name, "CmdReserveSpaceForCommandsNVX")) + return (PFN_vkVoidFunction)CmdReserveSpaceForCommandsNVX; + if (!strcmp(name, "CreateIndirectCommandsLayoutNVX")) + return (PFN_vkVoidFunction)CreateIndirectCommandsLayoutNVX; + if (!strcmp(name, "DestroyIndirectCommandsLayoutNVX")) + return (PFN_vkVoidFunction)DestroyIndirectCommandsLayoutNVX; + if (!strcmp(name, "CreateObjectTableNVX")) + return (PFN_vkVoidFunction)CreateObjectTableNVX; + if (!strcmp(name, "DestroyObjectTableNVX")) + return (PFN_vkVoidFunction)DestroyObjectTableNVX; + if (!strcmp(name, "RegisterObjectsNVX")) + return (PFN_vkVoidFunction)RegisterObjectsNVX; + if (!strcmp(name, "UnregisterObjectsNVX")) + return (PFN_vkVoidFunction)UnregisterObjectsNVX; + } + if (device_data->ext_display_control_enabled) { + if (!strcmp(name, "DisplayPowerControlEXT")) + return (PFN_vkVoidFunction)DisplayPowerControlEXT; + if (!strcmp(name, "RegisterDeviceEventEXT")) + return (PFN_vkVoidFunction)RegisterDeviceEventEXT; + if (!strcmp(name, "RegisterDisplayEventEXT")) + return (PFN_vkVoidFunction)RegisterDisplayEventEXT; + if (!strcmp(name, "GetSwapchainCounterEXT")) + return (PFN_vkVoidFunction)GetSwapchainCounterEXT; + } + } + + return NULL; +} + +static inline PFN_vkVoidFunction InterceptInstanceExtensionCommand(const char *name) { + if (!name || name[0] != 'v' || name[1] != 'k') + return NULL; + + name += 2; + + // VK_KHR_get_physical_device_properties2 Extension + if (!strcmp(name, "GetPhysicalDeviceFeatures2KHR")) + return (PFN_vkVoidFunction)GetPhysicalDeviceFeatures2KHR; + if (!strcmp(name, "GetPhysicalDeviceProperties2KHR")) + return (PFN_vkVoidFunction)GetPhysicalDeviceProperties2KHR; + if (!strcmp(name, "GetPhysicalDeviceFormatProperties2KHR")) + return (PFN_vkVoidFunction)GetPhysicalDeviceFormatProperties2KHR; + if (!strcmp(name, "GetPhysicalDeviceImageFormatProperties2KHR")) + return (PFN_vkVoidFunction)GetPhysicalDeviceImageFormatProperties2KHR; + if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties2KHR")) + return (PFN_vkVoidFunction)GetPhysicalDeviceQueueFamilyProperties2KHR; + if (!strcmp(name, "GetPhysicalDeviceMemoryProperties2KHR")) + return (PFN_vkVoidFunction)GetPhysicalDeviceMemoryProperties2KHR; + if (!strcmp(name, "GetPhysicalDeviceSparseImageFormatProperties2KHR")) + return (PFN_vkVoidFunction)GetPhysicalDeviceSparseImageFormatProperties2KHR; + // VK_NVX_device_generated_commands Extension + if (!strcmp(name, "GetPhysicalDeviceGeneratedCommandsPropertiesNVX")) + return (PFN_vkVoidFunction)GetPhysicalDeviceGeneratedCommandsPropertiesNVX; + // VK_EXT_direct_mode_display Extension + if (!strcmp(name, "ReleaseDisplayEXT")) + return (PFN_vkVoidFunction)ReleaseDisplayEXT; +#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT + // VK_EXT_acquire_xlib_display Extension + if (!strcmp(name, "AcquireXlibDisplayEXT")) + return (PFN_vkVoidFunction)AcquireXlibDisplayEXT; + if (!strcmp(name, "GetRandROutputDisplayEXT")) + return (PFN_vkVoidFunction)GetRandROutputDisplayEXT; +#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT + // VK_EXT_display_surface_counter Extension + if (!strcmp(name, "GetPhysicalDeviceSurfaceCapabilities2EXT")) + return (PFN_vkVoidFunction)GetPhysicalDeviceSurfaceCapabilities2EXT; + + return NULL; +} + static inline PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkDevice device) { if (device) { layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); @@ -4345,6 +4841,10 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, cons if (addr) { return addr; } + addr = InterceptDeviceExtensionCommand(funcName, device); + if (addr) { + return addr; + } if (get_dispatch_table(ot_device_table_map, device)->GetDeviceProcAddr == NULL) { return NULL; } @@ -4373,12 +4873,25 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance if (addr) { return addr; } + addr = InterceptInstanceExtensionCommand(funcName); + if (addr) { + return addr; + } if (get_dispatch_table(ot_instance_table_map, instance)->GetInstanceProcAddr == NULL) { return NULL; } return get_dispatch_table(ot_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName); } +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + assert(instance); + + if (get_dispatch_table(ot_instance_table_map, instance)->GetPhysicalDeviceProcAddr == NULL) { + return NULL; + } + return get_dispatch_table(ot_instance_table_map, instance)->GetPhysicalDeviceProcAddr(instance, funcName); +} + } // namespace object_tracker // vk_layer_logging.h expects these to be defined @@ -4433,3 +4946,27 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionPropert assert(physicalDevice == VK_NULL_HANDLE); return object_tracker::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties); } + +VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + return object_tracker::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) { + object_tracker::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; +} diff --git a/layers/object_tracker.h b/layers/object_tracker.h index 078e7f09..d34bd038 100644 --- a/layers/object_tracker.h +++ b/layers/object_tracker.h @@ -98,6 +98,8 @@ struct layer_data { bool wsi_display_swapchain_enabled; bool wsi_display_extension_enabled; bool objtrack_extensions_enabled; + bool nvx_device_generated_commands_enabled; + bool ext_display_control_enabled; // The following are for keeping track of the temporary callbacks that can // be used in vkCreateInstance and vkDestroyInstance: diff --git a/layers/parameter_validation.cpp b/layers/parameter_validation.cpp index 970fc7bb..332fd8b8 100644 --- a/layers/parameter_validation.cpp +++ b/layers/parameter_validation.cpp @@ -77,14 +77,28 @@ struct layer_data { VkPhysicalDeviceFeatures physical_device_features = {}; VkPhysicalDevice physical_device = VK_NULL_HANDLE; - bool swapchain_enabled = false; - bool display_swapchain_enabled = false; - bool amd_negative_viewport_height_enabled = false; - bool nvx_device_generated_commands_enabled = false; + union loader_device_extension_enables { + struct { + bool khr_swapchain_enabled : 1; + bool khr_display_swapchain_enabled : 1; + bool khr_maintenance1 : 1; + bool ext_debug_marker : 1; + bool amd_negative_viewport_height : 1; + bool nv_external_memory : 1; + bool nv_external_memory_win32 : 1; + bool nvx_device_generated_commands : 1; + }; + uint64_t padding[4]; + } enables; + + layer_data() { + memset(enables.padding, 0, sizeof(uint64_t) * 4); + } VkLayerDispatchTable dispatch_table = {}; }; +static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION; static std::unordered_map<void *, layer_data *> layer_data_map; static std::unordered_map<void *, instance_layer_data *> instance_layer_data_map; @@ -1559,61 +1573,71 @@ static void CheckInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateI if (strcmp(name, VK_KHR_SURFACE_EXTENSION_NAME) == 0) { instance_data->extensions.surface_enabled = true; - } #ifdef VK_USE_PLATFORM_XLIB_KHR - if (strcmp(name, VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) { + } else if (strcmp(name, VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) { instance_data->extensions.xlib_enabled = true; - } #endif #ifdef VK_USE_PLATFORM_XCB_KHR - if (strcmp(name, VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) { + } else if (strcmp(name, VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) { instance_data->extensions.xcb_enabled = true; - } #endif #ifdef VK_USE_PLATFORM_WAYLAND_KHR - if (strcmp(name, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) { + } else if (strcmp(name, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) { instance_data->extensions.wayland_enabled = true; - } #endif #ifdef VK_USE_PLATFORM_MIR_KHR - if (strcmp(name, VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) { + } else if (strcmp(name, VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) { instance_data->extensions.mir_enabled = true; - } #endif #ifdef VK_USE_PLATFORM_ANDROID_KHR - if (strcmp(name, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) { + } else if (strcmp(name, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) { instance_data->extensions.android_enabled = true; - } #endif #ifdef VK_USE_PLATFORM_WIN32_KHR - if (strcmp(name, VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) { + } else if (strcmp(name, VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) { instance_data->extensions.win32_enabled = true; - } #endif - if (strcmp(name, VK_KHR_DISPLAY_EXTENSION_NAME) == 0) { + } else if (strcmp(name, VK_KHR_DISPLAY_EXTENSION_NAME) == 0) { instance_data->extensions.display_enabled = true; + } else if (strcmp(name, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { + instance_data->extensions.khr_get_phys_dev_properties2_enabled = true; + } else if (strcmp(name, VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME) == 0) { + instance_data->extensions.nv_external_memory_capabilities_enabled = true; +#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT + } else if (strcmp(name, VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME) == 0) { + instance_data->extensions.ext_acquire_xlib_display_enabled = true; +#endif + } else if (strcmp(name, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME) == 0) { + instance_data->extensions.ext_direct_mode_display_enabled = true; + } else if (strcmp(name, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME) == 0) { + instance_data->extensions.ext_display_surface_counter_enabled = true; + } else if (strcmp(name, VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME) == 0) { + instance_data->extensions.nv_external_memory_capabilities_enabled = true; } } } static void CheckDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) { layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); - device_data->swapchain_enabled = false; - device_data->display_swapchain_enabled = false; - device_data->amd_negative_viewport_height_enabled = false; - for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) { - device_data->swapchain_enabled = true; - } - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME) == 0) { - device_data->display_swapchain_enabled = true; - } - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME) == 0) { - device_data->amd_negative_viewport_height_enabled = true; - } - if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME) == 0) { - device_data->nvx_device_generated_commands_enabled = true; + device_data->enables.khr_swapchain_enabled = true; + } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME) == 0) { + device_data->enables.khr_display_swapchain_enabled = true; + } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MAINTENANCE1_EXTENSION_NAME) == 0) { + device_data->enables.khr_maintenance1 = true; +#ifdef VK_USE_PLATFORM_WIN32_KHR + } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME) == 0) { + device_data->enables.nv_external_memory_win32 = true; +#endif + } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_MARKER_EXTENSION_NAME) == 0) { + device_data->enables.ext_debug_marker = true; + } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME) == 0) { + device_data->enables.amd_negative_viewport_height = true; + } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME) == 0) { + device_data->enables.nv_external_memory = true; + } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME) == 0) { + device_data->enables.nvx_device_generated_commands = true; } } } @@ -3995,7 +4019,7 @@ static bool preCmdSetViewport(layer_data *my_data, uint32_t viewport_count, cons } bool invalid_height = (viewport.height <= 0 || viewport.height > limits.maxViewportDimensions[1]); - if (my_data->amd_negative_viewport_height_enabled && (viewport.height < 0)) { + if (my_data->enables.amd_negative_viewport_height && (viewport.height < 0)) { // VALIDATION_ERROR_01790 invalid_height = false; } @@ -4817,9 +4841,9 @@ VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevi ->dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties); } -static bool require_device_extension(layer_data *my_data, bool layer_data::*flag, char const *function_name, char const *extension_name) +static bool require_device_extension(layer_data *my_data, bool flag, char const *function_name, char const *extension_name) { - if (!(my_data->*flag)) { + if (!flag) { return log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, EXTENSION_NOT_ENABLED, LayerName, "%s() called even though the %s extension was not enabled for this VkDevice.", @@ -4838,7 +4862,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapc layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::swapchain_enabled, "vkCreateSwapchainKHR", VK_KHR_SWAPCHAIN_EXTENSION_NAME); + skip |= require_device_extension(my_data, my_data->enables.khr_swapchain_enabled, "vkCreateSwapchainKHR", VK_KHR_SWAPCHAIN_EXTENSION_NAME); skip |= parameter_validation_vkCreateSwapchainKHR(my_data->report_data, pCreateInfo, pAllocator, pSwapchain); @@ -4858,7 +4882,7 @@ VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchai layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::swapchain_enabled, "vkGetSwapchainImagesKHR", VK_KHR_SWAPCHAIN_EXTENSION_NAME); + skip |= require_device_extension(my_data, my_data->enables.khr_swapchain_enabled, "vkGetSwapchainImagesKHR", VK_KHR_SWAPCHAIN_EXTENSION_NAME); skip |= parameter_validation_vkGetSwapchainImagesKHR(my_data->report_data, swapchain, pSwapchainImageCount, pSwapchainImages); @@ -4879,7 +4903,7 @@ VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainK layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::swapchain_enabled, "vkAcquireNextImageKHR", VK_KHR_SWAPCHAIN_EXTENSION_NAME); + skip |= require_device_extension(my_data, my_data->enables.khr_swapchain_enabled, "vkAcquireNextImageKHR", VK_KHR_SWAPCHAIN_EXTENSION_NAME); skip |= parameter_validation_vkAcquireNextImageKHR(my_data->report_data, swapchain, timeout, semaphore, fence, pImageIndex); @@ -4899,7 +4923,7 @@ VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInf layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::swapchain_enabled, "vkQueuePresentKHR", VK_KHR_SWAPCHAIN_EXTENSION_NAME); + skip |= require_device_extension(my_data, my_data->enables.khr_swapchain_enabled, "vkQueuePresentKHR", VK_KHR_SWAPCHAIN_EXTENSION_NAME); skip |= parameter_validation_vkQueuePresentKHR(my_data->report_data, pPresentInfo); @@ -4917,7 +4941,7 @@ VKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(VkDevice device, VkSwapchainKHR s layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::swapchain_enabled, "vkDestroySwapchainKHR", VK_KHR_SWAPCHAIN_EXTENSION_NAME); + skip |= require_device_extension(my_data, my_data->enables.khr_swapchain_enabled, "vkDestroySwapchainKHR", VK_KHR_SWAPCHAIN_EXTENSION_NAME); /* No generated validation function for this call */ @@ -5280,8 +5304,8 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateAndroidSurfaceKHR(VkInstance instance, cons assert(my_data != NULL); bool skip = false; - skip |= require_instance_extension(instance, &instance_extension_enables::android_enabled, - "vkCreateAndroidSurfaceKHR", VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); + skip |= require_instance_extension(instance, &instance_extension_enables::android_enabled, "vkCreateAndroidSurfaceKHR", + VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); skip |= parameter_validation_vkCreateAndroidSurfaceKHR(my_data->report_data, pCreateInfo, pAllocator, pSurface); @@ -5303,10 +5327,11 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateSharedSwapchainsKHR(VkDevice device, uint32 auto my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::display_swapchain_enabled, "vkCreateSharedSwapchainsKHR", VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME); + skip |= require_device_extension(my_data, my_data->enables.khr_display_swapchain_enabled, "vkCreateSharedSwapchainsKHR", + VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME); skip |= parameter_validation_vkCreateSharedSwapchainsKHR(my_data->report_data, swapchainCount, pCreateInfos, pAllocator, - pSwapchains); + pSwapchains); if (!skip) { result = my_data->dispatch_table.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains); @@ -5409,8 +5434,8 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayModeKHR(VkPhysicalDevice physicalDev auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); assert(my_data != NULL); - skip |= require_instance_extension(physicalDevice, &instance_extension_enables::display_enabled, - "vkCreateDisplayModeKHR", VK_KHR_DISPLAY_EXTENSION_NAME); + skip |= require_instance_extension(physicalDevice, &instance_extension_enables::display_enabled, "vkCreateDisplayModeKHR", + VK_KHR_DISPLAY_EXTENSION_NAME); // No parameter validation function for this call? @@ -5451,8 +5476,8 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayPlaneSurfaceKHR(VkInstance instance, auto my_data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map); assert(my_data != NULL); - skip |= require_instance_extension(instance, &instance_extension_enables::display_enabled, - "vkCreateDisplayPlaneSurfaceKHR", VK_KHR_DISPLAY_EXTENSION_NAME); + skip |= require_instance_extension(instance, &instance_extension_enables::display_enabled, "vkCreateDisplayPlaneSurfaceKHR", + VK_KHR_DISPLAY_EXTENSION_NAME); // No parameter validation function for this call? @@ -5465,13 +5490,204 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayPlaneSurfaceKHR(VkInstance instance, return result; } -// VK_EXT_debug_marker Extension +// Definitions for the VK_KHR_get_physical_device_properties2 extension + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR *pFeatures) { + bool skip_call = false; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + + skip_call |= + require_instance_extension(physicalDevice, &instance_extension_enables::khr_get_phys_dev_properties2_enabled, + "vkGetPhysicalDeviceFeatures2KHR", VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + + skip_call |= parameter_validation_vkGetPhysicalDeviceFeatures2KHR(my_data->report_data, pFeatures); + + if (!skip_call) { + my_data->dispatch_table.GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures); + } +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2KHR *pProperties) { + bool skip_call = false; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + + skip_call |= + require_instance_extension(physicalDevice, &instance_extension_enables::khr_get_phys_dev_properties2_enabled, + "vkGetPhysicalDeviceProperties2KHR", VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + + skip_call |= parameter_validation_vkGetPhysicalDeviceProperties2KHR(my_data->report_data, pProperties); + + if (!skip_call) { + my_data->dispatch_table.GetPhysicalDeviceProperties2KHR(physicalDevice, pProperties); + } +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format, + VkFormatProperties2KHR *pFormatProperties) { + bool skip_call = false; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + + skip_call |= require_instance_extension(physicalDevice, &instance_extension_enables::khr_get_phys_dev_properties2_enabled, + "vkGetPhysicalDeviceFormatProperties2KHR", + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + + skip_call |= parameter_validation_vkGetPhysicalDeviceFormatProperties2KHR(my_data->report_data, format, pFormatProperties); + + if (!skip_call) { + my_data->dispatch_table.GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, pFormatProperties); + } +} + +VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties2KHR( + VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo, + VkImageFormatProperties2KHR *pImageFormatProperties) { + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + bool skip_call = false; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + + skip_call |= require_instance_extension(physicalDevice, &instance_extension_enables::khr_get_phys_dev_properties2_enabled, + "vkGetPhysicalDeviceImageFormatProperties2KHR", + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + + skip_call |= parameter_validation_vkGetPhysicalDeviceImageFormatProperties2KHR(my_data->report_data, pImageFormatInfo, + pImageFormatProperties); + + if (!skip_call) { + result = my_data->dispatch_table.GetPhysicalDeviceImageFormatProperties2KHR(physicalDevice, pImageFormatInfo, + pImageFormatProperties); + validate_result(my_data->report_data, "vkGetPhysicalDeviceImageFormatProperties2KHR", result); + } + + return result; +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice, + uint32_t *pQueueFamilyPropertyCount, + VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { + bool skip_call = false; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + + skip_call |= require_instance_extension(physicalDevice, &instance_extension_enables::khr_get_phys_dev_properties2_enabled, + "vkGetPhysicalDeviceQueueFamilyProperties2KHR", + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + + skip_call |= parameter_validation_vkGetPhysicalDeviceQueueFamilyProperties2KHR(my_data->report_data, pQueueFamilyPropertyCount, + pQueueFamilyProperties); + + if (!skip_call) { + my_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount, + pQueueFamilyProperties); + } +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties2KHR(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties) { + bool skip_call = false; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + + skip_call |= require_instance_extension(physicalDevice, &instance_extension_enables::khr_get_phys_dev_properties2_enabled, + "vkGetPhysicalDeviceMemoryProperties2KHR", + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + + skip_call |= parameter_validation_vkGetPhysicalDeviceMemoryProperties2KHR(my_data->report_data, pMemoryProperties); + + if (!skip_call) { + my_data->dispatch_table.GetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties); + } +} + +VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties2KHR( + VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount, + VkSparseImageFormatProperties2KHR *pProperties) { + bool skip_call = false; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + + skip_call |= require_instance_extension(physicalDevice, &instance_extension_enables::khr_get_phys_dev_properties2_enabled, + "vkGetPhysicalDeviceSparseImageFormatProperties2KHR", + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + + skip_call |= parameter_validation_vkGetPhysicalDeviceSparseImageFormatProperties2KHR(my_data->report_data, pFormatInfo, + pPropertyCount, pProperties); + + if (!skip_call) { + my_data->dispatch_table.GetPhysicalDeviceSparseImageFormatProperties2KHR(physicalDevice, pFormatInfo, pPropertyCount, + pProperties); + } +} + +// Definitions for the VK_KHR_maintenance1 extension + +VKAPI_ATTR void VKAPI_CALL TrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlagsKHR flags) { + bool skip_call = false; + layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + assert(my_data != NULL); + + skip_call |= require_device_extension(my_data, my_data->enables.khr_maintenance1, "vkTrimCommandPoolKHR", + VK_KHR_MAINTENANCE1_EXTENSION_NAME); + + skip_call |= parameter_validation_vkTrimCommandPoolKHR(my_data->report_data, commandPool, flags); + + if (!skip_call) { + my_data->dispatch_table.TrimCommandPoolKHR(device, commandPool, flags); + } +} + +// Definitions for the VK_EXT_acquire_xlib_display extension + +#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT +VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, VkDisplayKHR display) { + + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + bool skip = false; + skip |= require_instance_extension(physicalDevice, &instance_extension_enables::ext_acquire_xlib_display_enabled, + "vkAcquireXlibDisplayEXT", VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME); + skip |= parameter_validation_vkAcquireXlibDisplayEXT(my_data->report_data, dpy, display); + if (!skip) { + result = my_data->dispatch_table.AcquireXlibDisplayEXT(physicalDevice, dpy, display); + validate_result(my_data->report_data, "vkAcquireXlibDisplayEXT", result); + } + return result; +} + +VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput, + VkDisplayKHR *pDisplay) { + + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + bool skip = false; + skip |= require_instance_extension(physicalDevice, &instance_extension_enables::ext_acquire_xlib_display_enabled, + "vkGetRandROutputDisplayEXT", VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME); + skip |= parameter_validation_vkGetRandROutputDisplayEXT(my_data->report_data, dpy, rrOutput, pDisplay); + if (!skip) { + result = my_data->dispatch_table.GetRandROutputDisplayEXT(physicalDevice, dpy, rrOutput, pDisplay); + validate_result(my_data->report_data, "vkGetRandROutputDisplayEXT", result); + } + return result; +} +#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT + +// Definitions for the VK_EXT_debug_marker Extension + VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(VkDevice device, VkDebugMarkerObjectTagInfoEXT *pTagInfo) { VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; bool skip = false; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); + skip |= require_device_extension(my_data, my_data->enables.ext_debug_marker, "vkDebugMarkerSetObjectTagEXT", + VK_EXT_DEBUG_MARKER_EXTENSION_NAME); + skip |= parameter_validation_vkDebugMarkerSetObjectTagEXT(my_data->report_data, pTagInfo); if (!skip) { @@ -5492,6 +5708,9 @@ VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(VkDevice device, VkDe layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); + skip |= require_device_extension(my_data, my_data->enables.ext_debug_marker, "vkDebugMarkerSetObjectNameEXT", + VK_EXT_DEBUG_MARKER_EXTENSION_NAME); + skip |= parameter_validation_vkDebugMarkerSetObjectNameEXT(my_data->report_data, pNameInfo); if (!skip) { @@ -5511,6 +5730,9 @@ VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); assert(my_data != NULL); + skip |= require_device_extension(my_data, my_data->enables.ext_debug_marker, "vkCmdDebugMarkerBeginEXT", + VK_EXT_DEBUG_MARKER_EXTENSION_NAME); + skip |= parameter_validation_vkCmdDebugMarkerBeginEXT(my_data->report_data, pMarkerInfo); if (!skip && my_data->dispatch_table.CmdDebugMarkerBeginEXT) { @@ -5523,6 +5745,9 @@ VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); assert(my_data != NULL); + skip |= require_device_extension(my_data, my_data->enables.ext_debug_marker, "vkCmdDebugMarkerInsertEXT", + VK_EXT_DEBUG_MARKER_EXTENSION_NAME); + skip |= parameter_validation_vkCmdDebugMarkerInsertEXT(my_data->report_data, pMarkerInfo); if (!skip && my_data->dispatch_table.CmdDebugMarkerInsertEXT) { @@ -5530,7 +5755,48 @@ VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer } } -// VK_NV_external_memory_capabilities Extension +// Definitions for the VK_EXT_direct_mode_display extension + +VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) { + + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + bool skip = false; + skip |= require_instance_extension(physicalDevice, &instance_extension_enables::ext_direct_mode_display_enabled, + "vkReleaseDisplayEXT", VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME); +#if 0 // Validation not automatically generated + skip |= parameter_validation_vkReleaseDisplayEXT(my_data->report_data, display); +#endif + if (!skip) { + result = my_data->dispatch_table.ReleaseDisplayEXT(physicalDevice, display); + validate_result(my_data->report_data, "vkGetRandROutputDisplayEXT", result); + } + return result; +} + +// Definitions for the VK_EXT_display_surface_counter extension + +VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, + VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { + + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); + assert(my_data != NULL); + bool skip = false; + skip |= require_instance_extension(physicalDevice, &instance_extension_enables::ext_display_surface_counter_enabled, + "vkGetPhysicalDeviceSurfaceCapabilities2EXT", VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME); + skip |= + parameter_validation_vkGetPhysicalDeviceSurfaceCapabilities2EXT(my_data->report_data, surface, pSurfaceCapabilities); + if (!skip) { + result = my_data->dispatch_table.GetPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, pSurfaceCapabilities); + validate_result(my_data->report_data, "vkGetPhysicalDeviceSurfaceCapabilities2EXT", result); + } + return result; +} + +// Definitions for the VK_NV_external_memory_capabilities Extension + VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceExternalImageFormatPropertiesNV( VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType, @@ -5541,6 +5807,10 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceExternalImageFormatPropertiesNV( auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); assert(my_data != NULL); + skip |= require_instance_extension(physicalDevice, &instance_extension_enables::nv_external_memory_capabilities_enabled, + "vkGetPhysicalDeviceExternalImageFormatPropertiesNV", + VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); + skip |= parameter_validation_vkGetPhysicalDeviceExternalImageFormatPropertiesNV( my_data->report_data, format, type, tiling, usage, flags, externalHandleType, pExternalImageFormatProperties); @@ -5554,8 +5824,9 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceExternalImageFormatPropertiesNV( return result; } -#ifdef VK_USE_PLATFORM_WIN32_KHR // VK_NV_external_memory_win32 Extension + +#ifdef VK_USE_PLATFORM_WIN32_KHR VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE *pHandle) { @@ -5564,6 +5835,9 @@ VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleNV(VkDevice device, VkDeviceM layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); + skip |= require_device_extension(my_data, my_data->enables.nv_external_memory_win32, "vkGetMemoryWin32HandleNV", + VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME); + skip |= parameter_validation_vkGetMemoryWin32HandleNV(my_data->report_data, memory, handleType, pHandle); if (!skip) { @@ -5574,37 +5848,31 @@ VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleNV(VkDevice device, VkDeviceM } #endif // VK_USE_PLATFORM_WIN32_KHR -// VK_NVX_device_generated_commands extension +// VK_NVX_device_generated_commands Extension VKAPI_ATTR void VKAPI_CALL CmdProcessCommandsNVX(VkCommandBuffer commandBuffer, const VkCmdProcessCommandsInfoNVX *pProcessCommandsInfo) { bool skip = false; - layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); - assert(device_data != nullptr); - debug_report_data *report_data = device_data->report_data; - - skip |= require_device_extension(device_data, &layer_data::nvx_device_generated_commands_enabled, "vkCmdProcessCommandsNVX", + layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); + assert(my_data != NULL); + skip |= require_device_extension(my_data, my_data->enables.nvx_device_generated_commands, "vkCmdProcessCommandsNVX", VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); - skip |= parameter_validation_vkCmdProcessCommandsNVX(report_data, pProcessCommandsInfo); - + skip |= parameter_validation_vkCmdProcessCommandsNVX(my_data->report_data, pProcessCommandsInfo); if (!skip) { - device_data->dispatch_table.CmdProcessCommandsNVX(commandBuffer, pProcessCommandsInfo); + my_data->dispatch_table.CmdProcessCommandsNVX(commandBuffer, pProcessCommandsInfo); } } VKAPI_ATTR void VKAPI_CALL CmdReserveSpaceForCommandsNVX(VkCommandBuffer commandBuffer, const VkCmdReserveSpaceForCommandsInfoNVX *pReserveSpaceInfo) { bool skip = false; - layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); - assert(device_data != nullptr); - debug_report_data *report_data = device_data->report_data; - - skip |= require_device_extension(device_data, &layer_data::nvx_device_generated_commands_enabled, - "vkCmdReserveSpaceForCommandsNVX", VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); - skip |= parameter_validation_vkCmdReserveSpaceForCommandsNVX(report_data, pReserveSpaceInfo); - + layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); + assert(my_data != NULL); + skip |= require_device_extension(my_data, my_data->enables.nvx_device_generated_commands, "vkCmdReserveSpaceForCommandsNVX", + VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); + skip |= parameter_validation_vkCmdReserveSpaceForCommandsNVX(my_data->report_data, pReserveSpaceInfo); if (!skip) { - device_data->dispatch_table.CmdReserveSpaceForCommandsNVX(commandBuffer, pReserveSpaceInfo); + my_data->dispatch_table.CmdReserveSpaceForCommandsNVX(commandBuffer, pReserveSpaceInfo); } } @@ -5616,13 +5884,12 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateIndirectCommandsLayoutNVX(VkDevice device, bool skip = false; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::nvx_device_generated_commands_enabled, - "vkCreateIndirectCommandsLayoutNVX", VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); + skip |= require_device_extension(my_data, my_data->enables.nvx_device_generated_commands, "vkCreateIndirectCommandsLayoutNVX", + VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); skip |= parameter_validation_vkCreateIndirectCommandsLayoutNVX(my_data->report_data, pCreateInfo, pAllocator, pIndirectCommandsLayout); if (!skip) { result = my_data->dispatch_table.CreateIndirectCommandsLayoutNVX(device, pCreateInfo, pAllocator, pIndirectCommandsLayout); - validate_result(my_data->report_data, "vkCreateIndirectCommandsLayoutNVX", result); } return result; @@ -5633,9 +5900,11 @@ VKAPI_ATTR void VKAPI_CALL DestroyIndirectCommandsLayoutNVX(VkDevice device, VkI bool skip = false; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::nvx_device_generated_commands_enabled, - "vkDestroyIndirectCommandsLayoutNVX", VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); + skip |= require_device_extension(my_data, my_data->enables.nvx_device_generated_commands, "vkDestroyIndirectCommandsLayoutNVX", + VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); +#if 0 // Validation not automatically generated skip |= parameter_validation_vkDestroyIndirectCommandsLayoutNVX(my_data->report_data, indirectCommandsLayout, pAllocator); +#endif if (!skip) { my_data->dispatch_table.DestroyIndirectCommandsLayoutNVX(device, indirectCommandsLayout, pAllocator); } @@ -5647,11 +5916,12 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateObjectTableNVX(VkDevice device, const VkObj bool skip = false; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::nvx_device_generated_commands_enabled, "vkCreateObjectTableNVX", + skip |= require_device_extension(my_data, my_data->enables.nvx_device_generated_commands, "vkCreateObjectTableNVX", VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); skip |= parameter_validation_vkCreateObjectTableNVX(my_data->report_data, pCreateInfo, pAllocator, pObjectTable); if (!skip) { result = my_data->dispatch_table.CreateObjectTableNVX(device, pCreateInfo, pAllocator, pObjectTable); + validate_result(my_data->report_data, "vkCreateObjectTableNVX", result); } return result; } @@ -5661,9 +5931,11 @@ VKAPI_ATTR void VKAPI_CALL DestroyObjectTableNVX(VkDevice device, VkObjectTableN bool skip = false; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::nvx_device_generated_commands_enabled, "vkDestroyObjectTableNVX", + skip |= require_device_extension(my_data, my_data->enables.nvx_device_generated_commands, "vkDestroyObjectTableNVX", VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); +#if 0 // Validation not automatically generated skip |= parameter_validation_vkDestroyObjectTableNVX(my_data->report_data, objectTable, pAllocator); +#endif if (!skip) { my_data->dispatch_table.DestroyObjectTableNVX(device, objectTable, pAllocator); } @@ -5676,12 +5948,13 @@ VKAPI_ATTR VkResult VKAPI_CALL RegisterObjectsNVX(VkDevice device, VkObjectTable bool skip = false; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::nvx_device_generated_commands_enabled, "vkRegisterObjectsNVX", + skip |= require_device_extension(my_data, my_data->enables.nvx_device_generated_commands, "vkRegisterObjectsNVX", VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); skip |= parameter_validation_vkRegisterObjectsNVX(my_data->report_data, objectTable, objectCount, ppObjectTableEntries, pObjectIndices); if (!skip) { result = my_data->dispatch_table.RegisterObjectsNVX(device, objectTable, objectCount, ppObjectTableEntries, pObjectIndices); + validate_result(my_data->report_data, "vkRegisterObjectsNVX", result); } return result; } @@ -5692,12 +5965,13 @@ VKAPI_ATTR VkResult VKAPI_CALL UnregisterObjectsNVX(VkDevice device, VkObjectTab bool skip = false; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); assert(my_data != NULL); - skip |= require_device_extension(my_data, &layer_data::nvx_device_generated_commands_enabled, "vkUnregisterObjectsNVX", + skip |= require_device_extension(my_data, my_data->enables.nvx_device_generated_commands, "vkUnregisterObjectsNVX", VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); skip |= parameter_validation_vkUnregisterObjectsNVX(my_data->report_data, objectTable, objectCount, pObjectEntryTypes, pObjectIndices); if (!skip) { result = my_data->dispatch_table.UnregisterObjectsNVX(device, objectTable, objectCount, pObjectEntryTypes, pObjectIndices); + validate_result(my_data->report_data, "vkUnregisterObjectsNVX", result); } return result; } @@ -5708,9 +5982,7 @@ VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceGeneratedCommandsPropertiesNVX(VkPhy bool skip = false; auto my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map); assert(my_data != NULL); - skip |= parameter_validation_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX(my_data->report_data, pFeatures, pLimits); - if (!skip) { my_data->dispatch_table.GetPhysicalDeviceGeneratedCommandsPropertiesNVX(physicalDevice, pFeatures, pLimits); } @@ -5724,6 +5996,10 @@ static PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkDevice static PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkInstance instance); +static PFN_vkVoidFunction intercept_extension_instance_command(const char *name, VkInstance instance); + +static PFN_vkVoidFunction intercept_extension_device_command(const char *name, VkDevice device); + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) { assert(device); @@ -5741,6 +6017,10 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, cons if (proc) return proc; + proc = intercept_extension_device_command(funcName, device); + if (proc) + return proc; + if (!data->dispatch_table.GetDeviceProcAddr) return nullptr; return data->dispatch_table.GetDeviceProcAddr(device, funcName); @@ -5765,6 +6045,9 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance if (!proc) proc = InterceptWsiEnabledCommand(funcName, instance); + if (!proc) + proc = intercept_extension_instance_command(funcName, instance); + if (proc) return proc; @@ -5773,6 +6056,15 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance return data->dispatch_table.GetInstanceProcAddr(instance, funcName); } +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + assert(instance); + auto data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map); + + if (!data->dispatch_table.GetPhysicalDeviceProcAddr) + return nullptr; + return data->dispatch_table.GetPhysicalDeviceProcAddr(instance, funcName); +} + static PFN_vkVoidFunction intercept_core_instance_command(const char *name) { static const struct { const char *name; @@ -5783,6 +6075,7 @@ static PFN_vkVoidFunction intercept_core_instance_command(const char *name) { {"vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance)}, {"vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice)}, {"vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices)}, + {"vk_layerGetPhysicalDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProcAddr)}, {"vkGetPhysicalDeviceProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProperties)}, {"vkGetPhysicalDeviceFeatures", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFeatures)}, {"vkGetPhysicalDeviceFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFormatProperties)}, @@ -5976,6 +6269,10 @@ static PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkDevice if (!strcmp(wsi_device_commands[i].name, name)) return wsi_device_commands[i].proc; } + + if (!strcmp("vkCreateSharedSwapchainsKHR", name)) { + return reinterpret_cast<PFN_vkVoidFunction>(CreateSharedSwapchainsKHR); + } } return nullptr; @@ -6034,6 +6331,70 @@ static PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkInstanc return nullptr; } +static PFN_vkVoidFunction intercept_extension_instance_command(const char *name, VkInstance instance) { + static const struct { + const char *name; + PFN_vkVoidFunction proc; + } extension_instance_commands[] = { + {"vkGetPhysicalDeviceFeatures2KHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFeatures2KHR)}, + {"vkGetPhysicalDeviceProperties2KHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProperties2KHR)}, + {"vkGetPhysicalDeviceFormatProperties2KHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFormatProperties2KHR)}, + {"vkGetPhysicalDeviceImageFormatProperties2KHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceImageFormatProperties2KHR)}, + {"vkGetPhysicalDeviceQueueFamilyProperties2KHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties2KHR)}, + {"vkGetPhysicalDeviceMemoryProperties2KHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMemoryProperties2KHR)}, + {"vkGetPhysicalDeviceSparseImageFormatProperties2KHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSparseImageFormatProperties2KHR)}, + // NV_external_memory_capabilities + {"vkGetPhysicalDeviceExternalImageFormatPropertiesNV", + reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceExternalImageFormatPropertiesNV)}, + // NVX_device_generated_commands + {"vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceGeneratedCommandsPropertiesNVX)}, + }; + + for (size_t i = 0; i < ARRAY_SIZE(extension_instance_commands); i++) { + if (!strcmp(extension_instance_commands[i].name, name)) + return extension_instance_commands[i].proc; + } + + return nullptr; +} + +static PFN_vkVoidFunction intercept_extension_device_command(const char *name, VkDevice device) { + struct ExtProc { + const char *name; + PFN_vkVoidFunction proc; + } extension_device_commands[] = { + // KHR_maintenance1 + {"vkTrimCommandPoolKHR", reinterpret_cast<PFN_vkVoidFunction>(TrimCommandPoolKHR)}, +#ifdef VK_USE_PLATFORM_WIN32_KHR + // NV_external_memory_win32 + {"vkGetMemoryWin32HandleNV", reinterpret_cast<PFN_vkVoidFunction>(GetMemoryWin32HandleNV)}, +#endif // VK_USE_PLATFORM_WIN32_KHR + // EXT_debug_marker + {"vkDebugMarkerSetObjectTagEXT", reinterpret_cast<PFN_vkVoidFunction>(DebugMarkerSetObjectTagEXT)}, + {"vkDebugMarkerSetObjectNameEXT", reinterpret_cast<PFN_vkVoidFunction>(DebugMarkerSetObjectNameEXT)}, + {"vkCmdDebugMarkerBeginEXT", reinterpret_cast<PFN_vkVoidFunction>(CmdDebugMarkerBeginEXT)}, + {"vkCmdDebugMarkerInsertEXT", reinterpret_cast<PFN_vkVoidFunction>(CmdDebugMarkerInsertEXT)}, + // NVX_device_generated_commands + {"vkCmdProcessCommandsNVX", reinterpret_cast<PFN_vkVoidFunction>(CmdProcessCommandsNVX)}, + {"vkCmdReserveSpaceForCommandsNVX", reinterpret_cast<PFN_vkVoidFunction>(CmdReserveSpaceForCommandsNVX)}, + {"vkCreateIndirectCommandsLayoutNVX", reinterpret_cast<PFN_vkVoidFunction>(CreateIndirectCommandsLayoutNVX)}, + {"vkDestroyIndirectCommandsLayoutNVX", reinterpret_cast<PFN_vkVoidFunction>(DestroyIndirectCommandsLayoutNVX)}, + {"vkCreateObjectTableNVX", reinterpret_cast<PFN_vkVoidFunction>(CreateObjectTableNVX)}, + {"vkDestroyObjectTableNVX", reinterpret_cast<PFN_vkVoidFunction>(DestroyObjectTableNVX)}, + {"vkRegisterObjectsNVX", reinterpret_cast<PFN_vkVoidFunction>(RegisterObjectsNVX)}, + {"vkUnregisterObjectsNVX", reinterpret_cast<PFN_vkVoidFunction>(UnregisterObjectsNVX)}, + }; + + if (device) { + for (size_t i = 0; i < ARRAY_SIZE(extension_device_commands); i++) { + if (!strcmp(extension_device_commands[i].name, name)) + return extension_device_commands[i].proc; + } + } + + return nullptr; +} + } // namespace parameter_validation // vk_layer_logging.h expects these to be defined @@ -6090,3 +6451,27 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { return parameter_validation::GetInstanceProcAddr(instance, funcName); } + +VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + return parameter_validation::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) { + parameter_validation::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; +} diff --git a/layers/parameter_validation_utils.h b/layers/parameter_validation_utils.h index 4e4fd812..7c6e605f 100644 --- a/layers/parameter_validation_utils.h +++ b/layers/parameter_validation_utils.h @@ -81,6 +81,11 @@ struct instance_extension_enables { bool android_enabled; bool win32_enabled; bool display_enabled; + bool khr_get_phys_dev_properties2_enabled; + bool ext_acquire_xlib_display_enabled; + bool ext_direct_mode_display_enabled; + bool ext_display_surface_counter_enabled; + bool nv_external_memory_capabilities_enabled; }; // String returned by string_VkStructureType for an unrecognized type. @@ -272,11 +277,10 @@ bool validate_struct_type(debug_report_data *report_data, const char *apiName, c } /** - * Validate an array of Vulkan structures. + * Validate an array of Vulkan structures * - * Verify that required count and array parameters are not NULL. If count - * is not NULL and its value is not optional, verify that it is not 0. - * If the array contains 1 or more structures, verify that each structure's + * Verify that required count and array parameters are not 0 or NULL. If + * the array contains 1 or more structures, verify that each structure's * sType field is set to the correct VkStructureType value. * * @param report_data debug_report_data object for routing validation messages. @@ -284,39 +288,41 @@ bool validate_struct_type(debug_report_data *report_data, const char *apiName, c * @param countName Name of count parameter. * @param arrayName Name of array parameter. * @param sTypeName Name of expected VkStructureType value. - * @param count Pointer to the number of elements in the array. + * @param count Number of elements in the array. * @param array Array to validate. * @param sType VkStructureType for structure validation. - * @param countPtrRequired The 'count' parameter may not be NULL when true. - * @param countValueRequired The '*count' value may not be 0 when true. + * @param countRequired The 'count' parameter may not be 0 when true. * @param arrayRequired The 'array' parameter may not be NULL when true. * @return Boolean value indicating that the call should be skipped. */ template <typename T> bool validate_struct_type_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName, - const ParameterName &arrayName, const char *sTypeName, const uint32_t *count, const T *array, - VkStructureType sType, bool countPtrRequired, bool countValueRequired, bool arrayRequired) { + const ParameterName &arrayName, const char *sTypeName, uint32_t count, const T *array, + VkStructureType sType, bool countRequired, bool arrayRequired) { bool skip_call = false; - if (count == NULL) { - if (countPtrRequired) { - skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, - REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as NULL", apiName, - countName.get_name().c_str()); - } + if ((count == 0) || (array == NULL)) { + skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired); } else { - skip_call |= validate_struct_type_array(report_data, apiName, countName, arrayName, sTypeName, (*count), array, sType, - countValueRequired, arrayRequired); + // Verify that all structs in the array have the correct type + for (uint32_t i = 0; i < count; ++i) { + if (array[i].sType != sType) { + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + __LINE__, INVALID_STRUCT_STYPE, LayerName, "%s: parameter %s[%d].sType must be %s", apiName, + arrayName.get_name().c_str(), i, sTypeName); + } + } } return skip_call; } /** - * Validate an array of Vulkan structures + * Validate an array of Vulkan structures. * - * Verify that required count and array parameters are not 0 or NULL. If - * the array contains 1 or more structures, verify that each structure's + * Verify that required count and array parameters are not NULL. If count + * is not NULL and its value is not optional, verify that it is not 0. + * If the array contains 1 or more structures, verify that each structure's * sType field is set to the correct VkStructureType value. * * @param report_data debug_report_data object for routing validation messages. @@ -324,30 +330,29 @@ bool validate_struct_type_array(debug_report_data *report_data, const char *apiN * @param countName Name of count parameter. * @param arrayName Name of array parameter. * @param sTypeName Name of expected VkStructureType value. - * @param count Number of elements in the array. + * @param count Pointer to the number of elements in the array. * @param array Array to validate. * @param sType VkStructureType for structure validation. - * @param countRequired The 'count' parameter may not be 0 when true. + * @param countPtrRequired The 'count' parameter may not be NULL when true. + * @param countValueRequired The '*count' value may not be 0 when true. * @param arrayRequired The 'array' parameter may not be NULL when true. * @return Boolean value indicating that the call should be skipped. */ template <typename T> bool validate_struct_type_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName, - const ParameterName &arrayName, const char *sTypeName, uint32_t count, const T *array, - VkStructureType sType, bool countRequired, bool arrayRequired) { + const ParameterName &arrayName, const char *sTypeName, uint32_t *count, const T *array, + VkStructureType sType, bool countPtrRequired, bool countValueRequired, bool arrayRequired) { bool skip_call = false; - if ((count == 0) || (array == NULL)) { - skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired); - } else { - // Verify that all structs in the array have the correct type - for (uint32_t i = 0; i < count; ++i) { - if (array[i].sType != sType) { - skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - __LINE__, INVALID_STRUCT_STYPE, LayerName, "%s: parameter %s[%d].sType must be %s", apiName, - arrayName.get_name().c_str(), i, sTypeName); - } + if (count == NULL) { + if (countPtrRequired) { + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as NULL", apiName, + countName.get_name().c_str()); } + } else { + skip_call |= validate_struct_type_array(report_data, apiName, countName, arrayName, sTypeName, (*count), array, sType, + countValueRequired, arrayRequired); } return skip_call; diff --git a/layers/swapchain.cpp b/layers/swapchain.cpp index c7f1ca0f..80eefcd1 100644 --- a/layers/swapchain.cpp +++ b/layers/swapchain.cpp @@ -39,6 +39,8 @@ static std::mutex global_lock; // The following is for logging error messages: static std::unordered_map<void *, layer_data *> layer_data_map; +static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION; + static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}}; static const VkLayerProperties swapchain_layer = { @@ -161,7 +163,6 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreat my_data->instance = *pInstance; my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); - my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames); @@ -1366,6 +1367,18 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance return pTable->GetInstanceProcAddr(instance, funcName); } +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + assert(instance); + + layer_data *my_data; + my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; + + if (pTable->GetPhysicalDeviceProcAddr == NULL) + return NULL; + return pTable->GetPhysicalDeviceProcAddr(instance, funcName); +} + static PFN_vkVoidFunction intercept_core_instance_command(const char *name) { static const struct { const char *name; @@ -1376,6 +1389,7 @@ static PFN_vkVoidFunction intercept_core_instance_command(const char *name) { {"vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance)}, {"vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice)}, {"vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices)}, + {"vk_layerGetPhysicalDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProcAddr)}, {"vkEnumerateInstanceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties)}, {"vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties)}, {"vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties)}, @@ -1537,3 +1551,27 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { return swapchain::GetInstanceProcAddr(instance, funcName); } + +VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + return swapchain::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) { + swapchain::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; +} diff --git a/layers/threading.cpp b/layers/threading.cpp index f73774c4..2f931e71 100644 --- a/layers/threading.cpp +++ b/layers/threading.cpp @@ -39,6 +39,8 @@ namespace threading { +static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION; + static void initThreading(layer_data *my_data, const VkAllocationCallbacks *pAllocator) { layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "google_threading"); @@ -220,6 +222,9 @@ VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevi return my_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties); } +// Need to prototype this call because it's internal and does not show up in vk.xml +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName); + static inline PFN_vkVoidFunction layer_intercept_instance_proc(const char *name) { if (!name || name[0] != 'v' || name[1] != 'k') return NULL; @@ -241,6 +246,8 @@ static inline PFN_vkVoidFunction layer_intercept_instance_proc(const char *name) return (PFN_vkVoidFunction)CreateDevice; if (!strcmp(name, "GetInstanceProcAddr")) return (PFN_vkVoidFunction)GetInstanceProcAddr; + if (!strcmp(name, "GetPhysicalDeviceProcAddr")) + return (PFN_vkVoidFunction)GetPhysicalDeviceProcAddr; return NULL; } @@ -289,6 +296,18 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance return pTable->GetInstanceProcAddr(instance, funcName); } +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + assert(instance); + + layer_data *my_data; + my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; + + if (pTable->GetPhysicalDeviceProcAddr == NULL) + return NULL; + return pTable->GetPhysicalDeviceProcAddr(instance, funcName); +} + VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) { @@ -446,3 +465,27 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { return threading::GetInstanceProcAddr(instance, funcName); } + +VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + return threading::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) { + threading::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; +} diff --git a/layers/unique_objects.cpp b/layers/unique_objects.cpp index df03daa1..dabdc041 100644 --- a/layers/unique_objects.cpp +++ b/layers/unique_objects.cpp @@ -51,6 +51,8 @@ namespace unique_objects { +static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION; + static void initUniqueObjects(layer_data *instance_data, const VkAllocationCallbacks *pAllocator) { layer_debug_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "google_unique_objects"); } @@ -262,11 +264,17 @@ static const VkLayerProperties globalLayerProps = {"VK_LAYER_GOOGLE_unique_objec 1, // implementationVersion "Google Validation Layer"}; +/// Declare prototype for these functions +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName); + static inline PFN_vkVoidFunction layer_intercept_proc(const char *name) { for (unsigned int i = 0; i < sizeof(procmap) / sizeof(procmap[0]); i++) { if (!strcmp(name, procmap[i].name)) return procmap[i].pFunc; } + if (0 == strcmp(name, "vk_layerGetPhysicalDeviceProcAddr")) { + return (PFN_vkVoidFunction)GetPhysicalDeviceProcAddr; + } return NULL; } @@ -337,6 +345,17 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance return disp_table->GetInstanceProcAddr(instance, funcName); } +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + assert(instance); + + layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + VkLayerInstanceDispatchTable *disp_table = instance_data->instance_dispatch_table; + if (disp_table->GetPhysicalDeviceProcAddr == NULL) { + return NULL; + } + return disp_table->GetPhysicalDeviceProcAddr(instance, funcName); +} + VKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) { const VkMemoryAllocateInfo *input_allocate_info = pAllocateInfo; @@ -749,3 +768,27 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionPropert assert(physicalDevice == VK_NULL_HANDLE); return unique_objects::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties); } + +VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { + return unique_objects::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) { + unique_objects::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; +} diff --git a/layers/vk_layer_table.cpp b/layers/vk_layer_table.cpp index d9ec3c5b..bc9062e7 100644 --- a/layers/vk_layer_table.cpp +++ b/layers/vk_layer_table.cpp @@ -155,6 +155,10 @@ VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_v layer_init_instance_dispatch_table(instance, pTable, gpa); + // Setup func pointers that are required but not externally exposed. These won't be added to the instance dispatch table by + // default. + pTable->GetPhysicalDeviceProcAddr = (PFN_GetPhysicalDeviceProcAddr)gpa(instance, "vk_layerGetPhysicalDeviceProcAddr"); + return pTable; } diff --git a/layers/windows/VkLayer_core_validation.json b/layers/windows/VkLayer_core_validation.json index f98be951..dff857fd 100644 --- a/layers/windows/VkLayer_core_validation.json +++ b/layers/windows/VkLayer_core_validation.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_LUNARG_core_validation", "type": "GLOBAL", "library_path": ".\\VkLayer_core_validation.dll", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "LunarG Validation Layer", "instance_extensions": [ diff --git a/layers/windows/VkLayer_image.json b/layers/windows/VkLayer_image.json index afc4205a..de1ae7e0 100644 --- a/layers/windows/VkLayer_image.json +++ b/layers/windows/VkLayer_image.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_LUNARG_image", "type": "GLOBAL", "library_path": ".\\VkLayer_image.dll", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "LunarG Validation Layer", "instance_extensions": [ diff --git a/layers/windows/VkLayer_object_tracker.json b/layers/windows/VkLayer_object_tracker.json index 5a9d966f..4f648729 100644 --- a/layers/windows/VkLayer_object_tracker.json +++ b/layers/windows/VkLayer_object_tracker.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_LUNARG_object_tracker", "type": "GLOBAL", "library_path": ".\\VkLayer_object_tracker.dll", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "LunarG Validation Layer", "instance_extensions": [ diff --git a/layers/windows/VkLayer_parameter_validation.json b/layers/windows/VkLayer_parameter_validation.json index a3ca3132..87046720 100644 --- a/layers/windows/VkLayer_parameter_validation.json +++ b/layers/windows/VkLayer_parameter_validation.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_LUNARG_parameter_validation", "type": "GLOBAL", "library_path": ".\\VkLayer_parameter_validation.dll", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "LunarG Validation Layer", "instance_extensions": [ diff --git a/layers/windows/VkLayer_swapchain.json b/layers/windows/VkLayer_swapchain.json index 527f107a..9715996f 100644 --- a/layers/windows/VkLayer_swapchain.json +++ b/layers/windows/VkLayer_swapchain.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_LUNARG_swapchain", "type": "GLOBAL", "library_path": ".\\VkLayer_swapchain.dll", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "LunarG Validation Layer", "instance_extensions": [ diff --git a/layers/windows/VkLayer_threading.json b/layers/windows/VkLayer_threading.json index ffb0c975..c9cd979a 100644 --- a/layers/windows/VkLayer_threading.json +++ b/layers/windows/VkLayer_threading.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_GOOGLE_threading", "type": "GLOBAL", "library_path": ".\\VkLayer_threading.dll", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "Google Validation Layer", "instance_extensions": [ diff --git a/layers/windows/VkLayer_unique_objects.json b/layers/windows/VkLayer_unique_objects.json index b46fa201..8f55bac5 100644 --- a/layers/windows/VkLayer_unique_objects.json +++ b/layers/windows/VkLayer_unique_objects.json @@ -4,7 +4,7 @@ "name": "VK_LAYER_GOOGLE_unique_objects", "type": "GLOBAL", "library_path": ".\\VkLayer_unique_objects.dll", - "api_version": "1.0.38", + "api_version": "1.0.39", "implementation_version": "1", "description": "Google Validation Layer" } |
