From 9e75fbc30dd45dbcdae2330ecb937bf1beb210d0 Mon Sep 17 00:00:00 2001 From: Mike Schuchardt Date: Wed, 18 Jan 2023 18:15:15 -0700 Subject: [PATCH 1/2] Fix null function pointers for layer extensions The capture layer should always return layer implementation function pointers for extensions that it implements, even if the underlying layers/driver do not support them. This fixes VK_EXT_tooling_info on Android 12 which could previously be enumerated but never returned a function pointer for vkGetPhysicalDeviceToolPropertiesEXT. --- layer/trace_layer.cpp | 86 +++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 23 deletions(-) diff --git a/layer/trace_layer.cpp b/layer/trace_layer.cpp index ece6405b41..3df2c89d98 100644 --- a/layer/trace_layer.cpp +++ b/layer/trace_layer.cpp @@ -1,5 +1,5 @@ /* -** Copyright (c) 2018-2020 Valve Corporation +** Copyright (c) 2018-2023 Valve Corporation ** Copyright (c) 2018-2023 LunarG, Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a @@ -54,16 +54,23 @@ const VkLayerProperties kLayerProps = { GFXRECON_PROJECT_VERSION_DESIGNATION }; -const std::array kDeviceExtensionProps = { - VkExtensionProperties{ "VK_EXT_tooling_info", 1 }, - VkExtensionProperties{ VK_EXT_DEBUG_MARKER_EXTENSION_NAME, VK_EXT_DEBUG_MARKER_SPEC_VERSION } +struct LayerExtensionProps +{ + VkExtensionProperties props; + std::vector instance_funcs; + std::vector device_funcs; }; -const std::unordered_set kProvidedDeviceFunctions = { "vkCmdDebugMarkerBeginEXT", - "vkCmdDebugMarkerEndEXT", - "vkCmdDebugMarkerInsertEXT", - "vkDebugMarkerSetObjectNameEXT", - "vkDebugMarkerSetObjectTagEXT" }; +const std::vector kDeviceExtensionProps = { + { VkExtensionProperties{ "VK_EXT_tooling_info", 1 }, { "vkGetPhysicalDeviceToolPropertiesEXT" }, {} }, + { VkExtensionProperties{ "VK_EXT_DEBUG_MARKER_EXTENSION_NAME", VK_EXT_DEBUG_MARKER_SPEC_VERSION }, + {}, + { "vkCmdDebugMarkerBeginEXT", + "vkCmdDebugMarkerEndEXT", + "vkCmdDebugMarkerInsertEXT", + "vkDebugMarkerSetObjectNameEXT", + "vkDebugMarkerSetObjectTagEXT" } }, +}; /// An alphabetical list of device extensions which we do not report upstream if /// other layers or ICDs expose them to us. @@ -266,19 +273,36 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance return reinterpret_cast(encode::CreateInstance); } + bool has_implementation = false; + + // Check for implementation in the next level if (instance != VK_NULL_HANDLE) { auto table = encode::GetInstanceTable(instance); if ((table != nullptr) && (table->GetInstanceProcAddr != nullptr)) { - result = table->GetInstanceProcAddr(instance, pName); + has_implementation = (table->GetInstanceProcAddr(instance, pName) != nullptr); + } + } + + // Check for implementation in the layer itself + if (!has_implementation) + { + for (const auto ext_props : kDeviceExtensionProps) + { + if (std::find(ext_props.instance_funcs.begin(), ext_props.instance_funcs.end(), pName) != + ext_props.instance_funcs.end()) + { + has_implementation = true; + break; + } } } - if ((result != nullptr) || (instance == VK_NULL_HANDLE)) + // Only intercept the requested function if there is an implementation available, or if + // the instance handle is null and we can't determine if it is available from the next level. + if (has_implementation || (instance == VK_NULL_HANDLE)) { - // Only check for a layer implementation of the requested function if it is available from the next level, or if - // the instance handle is null and we can't determine if it is available from the next level. const auto entry = func_table.find(pName); if (entry != func_table.end()) @@ -307,22 +331,38 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, cons if (device != VK_NULL_HANDLE) { + bool has_implementation = false; + + // Check for implementation in the next level auto table = encode::GetDeviceTable(device); if ((table != nullptr) && (table->GetDeviceProcAddr != nullptr)) { - result = table->GetDeviceProcAddr(device, pName); + has_implementation = (table->GetDeviceProcAddr(device, pName) != nullptr); + } - if (result != nullptr || (kProvidedDeviceFunctions.find(pName) != kProvidedDeviceFunctions.end())) + // Check for implementation in the layer itself + if (!has_implementation) + { + for (const auto ext_props : kDeviceExtensionProps) { - // Only check for a layer implementation of the requested function if it is available from the next - // level or if we are providing the implementation ourselves. - const auto entry = func_table.find(pName); - if (entry != func_table.end()) + if (std::find(ext_props.device_funcs.begin(), ext_props.device_funcs.end(), pName) != + ext_props.device_funcs.end()) { - result = entry->second; + has_implementation = true; + break; } } } + + // Only intercept the requested function if there is an implementation available + if (has_implementation) + { + const auto entry = func_table.find(pName); + if (entry != func_table.end()) + { + result = entry->second; + } + } } return result; @@ -380,7 +420,7 @@ VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevi for (uint32_t i = 0; i < extension_count; ++i) { - pProperties[i] = kDeviceExtensionProps[i]; + pProperties[i] = kDeviceExtensionProps[i].props; } } } @@ -422,13 +462,13 @@ VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevi std::find_if(device_extension_properties.begin(), device_extension_properties.end(), [&provided_prop](const VkExtensionProperties& downstream_prop) { - return util::platform::StringCompare(provided_prop.extensionName, + return util::platform::StringCompare(provided_prop.props.extensionName, downstream_prop.extensionName, VK_MAX_EXTENSION_NAME_SIZE) == 0; }) == device_extension_properties.end(); if (append_provided_prop) { - device_extension_properties.push_back(provided_prop); + device_extension_properties.push_back(provided_prop.props); } } } From b794188008da7c73eb9abacedce3b1c66f6322a3 Mon Sep 17 00:00:00 2001 From: Mike Schuchardt Date: Tue, 17 Jan 2023 16:29:35 -0700 Subject: [PATCH 2/2] Add capture support for VK_ANDROID_frame_boundary Capture the vkFrameBoundaryANDROID function and treat it as a frame delimiter. Since this is a private extension, this change also includes a mechanism to extend the vk.xml tree before the code generators are invoked. --- android/gradlew | 0 framework/decode/file_processor.cpp | 1 + .../encode/custom_vulkan_encoder_commands.h | 10 ++++++ framework/encode/vulkan_capture_manager.h | 5 +++ framework/format/VK_ANDROID_frame_boundary.h | 30 +++++++++++++++++ framework/format/api_call_id.h | 5 +-- framework/format/platform_types.h | 5 +-- .../generated/generated_layer_func_table.h | 1 + .../generated_vulkan_api_call_encoders.cpp | 33 +++++++++++++++++++ .../generated_vulkan_api_call_encoders.h | 5 +++ .../generated/generated_vulkan_consumer.h | 6 ++++ .../generated/generated_vulkan_decoder.cpp | 23 +++++++++++++ .../generated/generated_vulkan_decoder.h | 2 ++ .../generated_vulkan_dispatch_table.h | 3 ++ .../generated_vulkan_export_json_consumer.cpp | 14 ++++++++ .../generated_vulkan_export_json_consumer.h | 6 ++++ .../generated_vulkan_replay_consumer.cpp | 13 ++++++++ .../generated_vulkan_replay_consumer.h | 6 ++++ .../VK_ANDROID_frame_boundary.xml | 18 ++++++++++ .../generated/vulkan_generators/gencode.py | 23 +++++++++++++ layer/trace_layer.cpp | 1 + 21 files changed, 206 insertions(+), 4 deletions(-) mode change 100644 => 100755 android/gradlew create mode 100644 framework/format/VK_ANDROID_frame_boundary.h create mode 100644 framework/generated/vulkan_generators/VK_ANDROID_frame_boundary.xml diff --git a/android/gradlew b/android/gradlew old mode 100644 new mode 100755 diff --git a/framework/decode/file_processor.cpp b/framework/decode/file_processor.cpp index 7527f6d519..b0edd4fa60 100644 --- a/framework/decode/file_processor.cpp +++ b/framework/decode/file_processor.cpp @@ -1899,6 +1899,7 @@ bool FileProcessor::IsFrameDelimiter(format::ApiCallId call_id) const // This code is deprecated and no new API calls should be added. Instead, end of frame markers are used to track // the file processor's frame count. return ((call_id == format::ApiCallId::ApiCall_vkQueuePresentKHR) || + (call_id == format::ApiCallId::ApiCall_vkFrameBoundaryANDROID) || (call_id == format::ApiCallId::ApiCall_IDXGISwapChain_Present) || (call_id == format::ApiCallId::ApiCall_IDXGISwapChain1_Present1)); } diff --git a/framework/encode/custom_vulkan_encoder_commands.h b/framework/encode/custom_vulkan_encoder_commands.h index 28a0ca0f43..f3613c1e87 100644 --- a/framework/encode/custom_vulkan_encoder_commands.h +++ b/framework/encode/custom_vulkan_encoder_commands.h @@ -270,6 +270,16 @@ struct CustomEncoderPostCall } }; +template <> +struct CustomEncoderPostCall +{ + template + static void Dispatch(VulkanCaptureManager* manager, Args... args) + { + manager->PostProcess_vkFrameBoundaryANDROID(args...); + } +}; + template <> struct CustomEncoderPostCall { diff --git a/framework/encode/vulkan_capture_manager.h b/framework/encode/vulkan_capture_manager.h index 0d0a473f01..fc7d748027 100644 --- a/framework/encode/vulkan_capture_manager.h +++ b/framework/encode/vulkan_capture_manager.h @@ -1224,6 +1224,11 @@ class VulkanCaptureManager : public CaptureManager void PostProcess_vkCmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); + void PostProcess_vkFrameBoundaryANDROID(VkDevice device, VkSemaphore semaphore, VkImage image) + { + EndFrame(); + } + #if defined(__ANDROID__) void OverrideGetPhysicalDeviceSurfacePresentModesKHR(uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); #endif diff --git a/framework/format/VK_ANDROID_frame_boundary.h b/framework/format/VK_ANDROID_frame_boundary.h new file mode 100644 index 0000000000..1b3013dcb3 --- /dev/null +++ b/framework/format/VK_ANDROID_frame_boundary.h @@ -0,0 +1,30 @@ +/* +** Copyright (c) 2023 LunarG, Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and associated documentation files (the "Software"), +** to deal in the Software without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Software, and to permit persons to whom the +** Software is furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +*/ + +#ifndef GFXRECON_VK_ANDROID_FRAME_BOUNDARY +#define GFXRECON_VK_ANDROID_FRAME_BOUNDARY + +#include "vulkan/vulkan.h" + +typedef void(VKAPI_PTR* PFN_vkFrameBoundaryANDROID)(VkDevice device, VkSemaphore semaphore, VkImage image); + +#endif diff --git a/framework/format/api_call_id.h b/framework/format/api_call_id.h index ed2a19e194..ccd7809797 100644 --- a/framework/format/api_call_id.h +++ b/framework/format/api_call_id.h @@ -1,6 +1,6 @@ /* -** Copyright (c) 2018-2021 Valve Corporation -** Copyright (c) 2018-2021 LunarG, Inc. +** Copyright (c) 2018-2023 Valve Corporation +** Copyright (c) 2018-2023 LunarG, Inc. ** Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All rights reserved. ** ** Permission is hereby granted, free of charge, to any person obtaining a @@ -699,6 +699,7 @@ enum ApiCallId : uint32_t ApiCall_vkGetRenderingAreaGranularityKHR = MakeApiCallId(ApiFamily_Vulkan, 0x12d9), ApiCall_vkGetDeviceImageSubresourceLayoutKHR = MakeApiCallId(ApiFamily_Vulkan, 0x12da), ApiCall_vkGetImageSubresourceLayout2KHR = MakeApiCallId(ApiFamily_Vulkan, 0x12db), + ApiCall_vkFrameBoundaryANDROID = MakeApiCallId(ApiFamily_Vulkan, 0x12dc), ApiCall_VulkanLast, diff --git a/framework/format/platform_types.h b/framework/format/platform_types.h index 8934dc927e..275a6d8532 100644 --- a/framework/format/platform_types.h +++ b/framework/format/platform_types.h @@ -1,6 +1,6 @@ /* -** Copyright (c) 2018-2020 Valve Corporation -** Copyright (c) 2018-2020 LunarG, Inc. +** Copyright (c) 2018-2023 Valve Corporation +** Copyright (c) 2018-2023 LunarG, Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ #define GFXRECON_PLATFORM_TYPES_H #include "util/logging.h" +#include "VK_ANDROID_frame_boundary.h" #include "vulkan/vulkan.h" diff --git a/framework/generated/generated_layer_func_table.h b/framework/generated/generated_layer_func_table.h index c13900ffe9..576bf067f9 100644 --- a/framework/generated/generated_layer_func_table.h +++ b/framework/generated/generated_layer_func_table.h @@ -410,6 +410,7 @@ const std::unordered_map func_table = { { "vkGetDeviceImageSubresourceLayoutKHR", reinterpret_cast(encode::GetDeviceImageSubresourceLayoutKHR) }, { "vkGetImageSubresourceLayout2KHR", reinterpret_cast(encode::GetImageSubresourceLayout2KHR) }, { "vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR", reinterpret_cast(encode::GetPhysicalDeviceCooperativeMatrixPropertiesKHR) }, + { "vkFrameBoundaryANDROID", reinterpret_cast(encode::FrameBoundaryANDROID) }, { "vkCreateDebugReportCallbackEXT", reinterpret_cast(encode::CreateDebugReportCallbackEXT) }, { "vkDestroyDebugReportCallbackEXT", reinterpret_cast(encode::DestroyDebugReportCallbackEXT) }, { "vkDebugReportMessageEXT", reinterpret_cast(encode::DebugReportMessageEXT) }, diff --git a/framework/generated/generated_vulkan_api_call_encoders.cpp b/framework/generated/generated_vulkan_api_call_encoders.cpp index e787ce4daf..17542fe28d 100644 --- a/framework/generated/generated_vulkan_api_call_encoders.cpp +++ b/framework/generated/generated_vulkan_api_call_encoders.cpp @@ -13532,6 +13532,39 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeMatrixPropertiesKHR( return result; } +VKAPI_ATTR void VKAPI_CALL FrameBoundaryANDROID( + VkDevice device, + VkSemaphore semaphore, + VkImage image) +{ + auto force_command_serialization = VulkanCaptureManager::Get()->GetForceCommandSerialization(); + std::shared_lock shared_api_call_lock; + std::unique_lock exclusive_api_call_lock; + if (force_command_serialization) + { + exclusive_api_call_lock = VulkanCaptureManager::AcquireExclusiveApiCallLock(); + } + else + { + shared_api_call_lock = VulkanCaptureManager::AcquireSharedApiCallLock(); + } + + CustomEncoderPreCall::Dispatch(VulkanCaptureManager::Get(), device, semaphore, image); + + auto encoder = VulkanCaptureManager::Get()->BeginApiCallCapture(format::ApiCallId::ApiCall_vkFrameBoundaryANDROID); + if (encoder) + { + encoder->EncodeHandleValue(device); + encoder->EncodeHandleValue(semaphore); + encoder->EncodeHandleValue(image); + VulkanCaptureManager::Get()->EndApiCallCapture(); + } + + GetDeviceTable(device)->FrameBoundaryANDROID(device, semaphore, image); + + CustomEncoderPostCall::Dispatch(VulkanCaptureManager::Get(), device, semaphore, image); +} + VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT( VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, diff --git a/framework/generated/generated_vulkan_api_call_encoders.h b/framework/generated/generated_vulkan_api_call_encoders.h index 95ca1eb253..dfbbc74574 100644 --- a/framework/generated/generated_vulkan_api_call_encoders.h +++ b/framework/generated/generated_vulkan_api_call_encoders.h @@ -1945,6 +1945,11 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeMatrixPropertiesKHR( uint32_t* pPropertyCount, VkCooperativeMatrixPropertiesKHR* pProperties); +VKAPI_ATTR void VKAPI_CALL FrameBoundaryANDROID( + VkDevice device, + VkSemaphore semaphore, + VkImage image); + VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT( VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, diff --git a/framework/generated/generated_vulkan_consumer.h b/framework/generated/generated_vulkan_consumer.h index 0959c9c8fc..a702336771 100644 --- a/framework/generated/generated_vulkan_consumer.h +++ b/framework/generated/generated_vulkan_consumer.h @@ -2473,6 +2473,12 @@ class VulkanConsumer : public VulkanConsumerBase PointerDecoder* pPropertyCount, StructPointerDecoder* pProperties) {} + virtual void Process_vkFrameBoundaryANDROID( + const ApiCallInfo& call_info, + format::HandleId device, + format::HandleId semaphore, + format::HandleId image) {} + virtual void Process_vkCreateDebugReportCallbackEXT( const ApiCallInfo& call_info, VkResult returnValue, diff --git a/framework/generated/generated_vulkan_decoder.cpp b/framework/generated/generated_vulkan_decoder.cpp index beb8f5e81b..012ef329c8 100644 --- a/framework/generated/generated_vulkan_decoder.cpp +++ b/framework/generated/generated_vulkan_decoder.cpp @@ -7699,6 +7699,26 @@ size_t VulkanDecoder::Decode_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR(c return bytes_read; } +size_t VulkanDecoder::Decode_vkFrameBoundaryANDROID(const ApiCallInfo& call_info, const uint8_t* parameter_buffer, size_t buffer_size) +{ + size_t bytes_read = 0; + + format::HandleId device; + format::HandleId semaphore; + format::HandleId image; + + bytes_read += ValueDecoder::DecodeHandleIdValue((parameter_buffer + bytes_read), (buffer_size - bytes_read), &device); + bytes_read += ValueDecoder::DecodeHandleIdValue((parameter_buffer + bytes_read), (buffer_size - bytes_read), &semaphore); + bytes_read += ValueDecoder::DecodeHandleIdValue((parameter_buffer + bytes_read), (buffer_size - bytes_read), &image); + + for (auto consumer : GetConsumers()) + { + consumer->Process_vkFrameBoundaryANDROID(call_info, device, semaphore, image); + } + + return bytes_read; +} + size_t VulkanDecoder::Decode_vkCreateDebugReportCallbackEXT(const ApiCallInfo& call_info, const uint8_t* parameter_buffer, size_t buffer_size) { size_t bytes_read = 0; @@ -14277,6 +14297,9 @@ void VulkanDecoder::DecodeFunctionCall(format::ApiCallId call_id, case format::ApiCallId::ApiCall_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR: Decode_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR(call_info, parameter_buffer, buffer_size); break; + case format::ApiCallId::ApiCall_vkFrameBoundaryANDROID: + Decode_vkFrameBoundaryANDROID(call_info, parameter_buffer, buffer_size); + break; case format::ApiCallId::ApiCall_vkCreateDebugReportCallbackEXT: Decode_vkCreateDebugReportCallbackEXT(call_info, parameter_buffer, buffer_size); break; diff --git a/framework/generated/generated_vulkan_decoder.h b/framework/generated/generated_vulkan_decoder.h index 15737df595..5deb49b365 100644 --- a/framework/generated/generated_vulkan_decoder.h +++ b/framework/generated/generated_vulkan_decoder.h @@ -761,6 +761,8 @@ class VulkanDecoder : public VulkanDecoderBase size_t Decode_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR(const ApiCallInfo& call_info, const uint8_t* parameter_buffer, size_t buffer_size); + size_t Decode_vkFrameBoundaryANDROID(const ApiCallInfo& call_info, const uint8_t* parameter_buffer, size_t buffer_size); + size_t Decode_vkCreateDebugReportCallbackEXT(const ApiCallInfo& call_info, const uint8_t* parameter_buffer, size_t buffer_size); size_t Decode_vkDestroyDebugReportCallbackEXT(const ApiCallInfo& call_info, const uint8_t* parameter_buffer, size_t buffer_size); diff --git a/framework/generated/generated_vulkan_dispatch_table.h b/framework/generated/generated_vulkan_dispatch_table.h index fa373fa4a1..ad2ce37af4 100644 --- a/framework/generated/generated_vulkan_dispatch_table.h +++ b/framework/generated/generated_vulkan_dispatch_table.h @@ -459,6 +459,7 @@ static VKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer2KHR(VkCommandBuffer, VkBuff static VKAPI_ATTR void VKAPI_CALL GetRenderingAreaGranularityKHR(VkDevice, const VkRenderingAreaInfoKHR*, VkExtent2D*) { GFXRECON_LOG_WARNING_ONCE("Unsupported function vkGetRenderingAreaGranularityKHR was called, resulting in no-op behavior."); } static VKAPI_ATTR void VKAPI_CALL GetDeviceImageSubresourceLayoutKHR(VkDevice, const VkDeviceImageSubresourceInfoKHR*, VkSubresourceLayout2KHR*) { GFXRECON_LOG_WARNING_ONCE("Unsupported function vkGetDeviceImageSubresourceLayoutKHR was called, resulting in no-op behavior."); } static VKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout2KHR(VkDevice, VkImage, const VkImageSubresource2KHR*, VkSubresourceLayout2KHR*) { GFXRECON_LOG_WARNING_ONCE("Unsupported function vkGetImageSubresourceLayout2KHR was called, resulting in no-op behavior."); } +static VKAPI_ATTR void VKAPI_CALL FrameBoundaryANDROID(VkDevice, VkSemaphore, VkImage) { GFXRECON_LOG_WARNING_ONCE("Unsupported function vkFrameBoundaryANDROID was called, resulting in no-op behavior."); } static VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(VkDevice, const VkDebugMarkerObjectTagInfoEXT*) { GFXRECON_LOG_WARNING_ONCE("Unsupported function vkDebugMarkerSetObjectTagEXT was called, resulting in no-op behavior."); return VK_SUCCESS; } static VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(VkDevice, const VkDebugMarkerObjectNameInfoEXT*) { GFXRECON_LOG_WARNING_ONCE("Unsupported function vkDebugMarkerSetObjectNameEXT was called, resulting in no-op behavior."); return VK_SUCCESS; } static VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerBeginEXT(VkCommandBuffer, const VkDebugMarkerMarkerInfoEXT*) { GFXRECON_LOG_WARNING_ONCE("Unsupported function vkCmdDebugMarkerBeginEXT was called, resulting in no-op behavior."); } @@ -1090,6 +1091,7 @@ struct DeviceTable PFN_vkGetRenderingAreaGranularityKHR GetRenderingAreaGranularityKHR{ noop::GetRenderingAreaGranularityKHR }; PFN_vkGetDeviceImageSubresourceLayoutKHR GetDeviceImageSubresourceLayoutKHR{ noop::GetDeviceImageSubresourceLayoutKHR }; PFN_vkGetImageSubresourceLayout2KHR GetImageSubresourceLayout2KHR{ noop::GetImageSubresourceLayout2KHR }; + PFN_vkFrameBoundaryANDROID FrameBoundaryANDROID{ noop::FrameBoundaryANDROID }; PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT{ noop::DebugMarkerSetObjectTagEXT }; PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT{ noop::DebugMarkerSetObjectNameEXT }; PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBeginEXT{ noop::CmdDebugMarkerBeginEXT }; @@ -1728,6 +1730,7 @@ static void LoadDeviceTable(PFN_vkGetDeviceProcAddr gpa, VkDevice device, Device LoadFunction(gpa, device, "vkGetRenderingAreaGranularityKHR", &table->GetRenderingAreaGranularityKHR); LoadFunction(gpa, device, "vkGetDeviceImageSubresourceLayoutKHR", &table->GetDeviceImageSubresourceLayoutKHR); LoadFunction(gpa, device, "vkGetImageSubresourceLayout2KHR", &table->GetImageSubresourceLayout2KHR); + LoadFunction(gpa, device, "vkFrameBoundaryANDROID", &table->FrameBoundaryANDROID); LoadFunction(gpa, device, "vkDebugMarkerSetObjectTagEXT", &table->DebugMarkerSetObjectTagEXT); LoadFunction(gpa, device, "vkDebugMarkerSetObjectNameEXT", &table->DebugMarkerSetObjectNameEXT); LoadFunction(gpa, device, "vkCmdDebugMarkerBeginEXT", &table->CmdDebugMarkerBeginEXT); diff --git a/framework/generated/generated_vulkan_export_json_consumer.cpp b/framework/generated/generated_vulkan_export_json_consumer.cpp index f74144ee88..417b903cb6 100644 --- a/framework/generated/generated_vulkan_export_json_consumer.cpp +++ b/framework/generated/generated_vulkan_export_json_consumer.cpp @@ -5628,6 +5628,20 @@ void VulkanExportJsonConsumer::Process_vkGetPhysicalDeviceCooperativeMatrixPrope WriteBlockEnd(); } +void VulkanExportJsonConsumer::Process_vkFrameBoundaryANDROID( + const ApiCallInfo& call_info, + format::HandleId device, + format::HandleId semaphore, + format::HandleId image) +{ + nlohmann::ordered_json& jdata = WriteApiCallStart(call_info, "vkFrameBoundaryANDROID"); + auto& args = jdata[NameArgs()]; + HandleToJson(args["device"], device, json_options_); + HandleToJson(args["semaphore"], semaphore, json_options_); + HandleToJson(args["image"], image, json_options_); + WriteBlockEnd(); +} + void VulkanExportJsonConsumer::Process_vkCreateDebugReportCallbackEXT( const ApiCallInfo& call_info, VkResult returnValue, diff --git a/framework/generated/generated_vulkan_export_json_consumer.h b/framework/generated/generated_vulkan_export_json_consumer.h index 1376f09733..0dbd2c1d34 100644 --- a/framework/generated/generated_vulkan_export_json_consumer.h +++ b/framework/generated/generated_vulkan_export_json_consumer.h @@ -2440,6 +2440,12 @@ class VulkanExportJsonConsumer : public VulkanExportJsonConsumerBase PointerDecoder* pPropertyCount, StructPointerDecoder* pProperties) override; + virtual void Process_vkFrameBoundaryANDROID( + const ApiCallInfo& call_info, + format::HandleId device, + format::HandleId semaphore, + format::HandleId image) override; + virtual void Process_vkCreateDebugReportCallbackEXT( const ApiCallInfo& call_info, VkResult returnValue, diff --git a/framework/generated/generated_vulkan_replay_consumer.cpp b/framework/generated/generated_vulkan_replay_consumer.cpp index 029c68eeb7..dc23ff3d1c 100644 --- a/framework/generated/generated_vulkan_replay_consumer.cpp +++ b/framework/generated/generated_vulkan_replay_consumer.cpp @@ -5440,6 +5440,19 @@ void VulkanReplayConsumer::Process_vkGetPhysicalDeviceCooperativeMatrixPropertie if (pProperties->IsNull()) { SetOutputArrayCount(physicalDevice, kPhysicalDeviceArrayGetPhysicalDeviceCooperativeMatrixPropertiesKHR, *out_pPropertyCount, &VulkanObjectInfoTable::GetPhysicalDeviceInfo); } } +void VulkanReplayConsumer::Process_vkFrameBoundaryANDROID( + const ApiCallInfo& call_info, + format::HandleId device, + format::HandleId semaphore, + format::HandleId image) +{ + VkDevice in_device = MapHandle(device, &VulkanObjectInfoTable::GetDeviceInfo); + VkSemaphore in_semaphore = MapHandle(semaphore, &VulkanObjectInfoTable::GetSemaphoreInfo); + VkImage in_image = MapHandle(image, &VulkanObjectInfoTable::GetImageInfo); + + GetDeviceTable(in_device)->FrameBoundaryANDROID(in_device, in_semaphore, in_image); +} + void VulkanReplayConsumer::Process_vkCreateDebugReportCallbackEXT( const ApiCallInfo& call_info, VkResult returnValue, diff --git a/framework/generated/generated_vulkan_replay_consumer.h b/framework/generated/generated_vulkan_replay_consumer.h index 09a70a5472..4d3f8d27b6 100644 --- a/framework/generated/generated_vulkan_replay_consumer.h +++ b/framework/generated/generated_vulkan_replay_consumer.h @@ -2473,6 +2473,12 @@ class VulkanReplayConsumer : public VulkanReplayConsumerBase PointerDecoder* pPropertyCount, StructPointerDecoder* pProperties) override; + virtual void Process_vkFrameBoundaryANDROID( + const ApiCallInfo& call_info, + format::HandleId device, + format::HandleId semaphore, + format::HandleId image) override; + virtual void Process_vkCreateDebugReportCallbackEXT( const ApiCallInfo& call_info, VkResult returnValue, diff --git a/framework/generated/vulkan_generators/VK_ANDROID_frame_boundary.xml b/framework/generated/vulkan_generators/VK_ANDROID_frame_boundary.xml new file mode 100644 index 0000000000..50fa71b3dc --- /dev/null +++ b/framework/generated/vulkan_generators/VK_ANDROID_frame_boundary.xml @@ -0,0 +1,18 @@ + + + + + void vkFrameBoundaryANDROID + VkDevice device + VkSemaphore semaphore + VkImage image + + + + + + + + + + \ No newline at end of file diff --git a/framework/generated/vulkan_generators/gencode.py b/framework/generated/vulkan_generators/gencode.py index dfa0d75405..a30a87d62f 100644 --- a/framework/generated/vulkan_generators/gencode.py +++ b/framework/generated/vulkan_generators/gencode.py @@ -145,6 +145,24 @@ def getExtraVulkanHeaders(extraHeadersDir): ] +def extend_xml(dest_tree, src_xml, debug=False): + '''Extend the parsed vk.xml registry tree with content from another xml file''' + def merge(dest, src): + '''Perform a recursive merge of src into dest''' + leaf_tags = ('command', 'enums', 'extension', 'feature', 'format', + 'platform', 'spirvcapability', 'spirvextension', 'tag', 'type') + for src_child in src: + dest_child = dest.find(src_child.tag) + if (src_child.tag in leaf_tags) or (not dest_child): + # stop descent and copy if the heirarchy diverges or we reach a leaf tag + dest.append(src_child) + else: + merge(dest_child, src_child) + merge(dest_tree.getroot(), etree.parse(src_xml).getroot()) + if debug: + dest_tree.write(os.path.splitext(src_xml)[0] + '_merged.xml') + + def make_gen_opts(args): """Returns a directory of [ generator function, generator options ] indexed by specified short names. The generator options incorporate the following @@ -890,6 +908,11 @@ def gen_target(args): ptag_member.set('len', 'tagSize') end_timer(args.time, '* Time to patch ElementTree =') + # Extend the vk.xml tree with XML files from the config dir + for filename in os.listdir(args.configs): + if filename.endswith('.xml'): + extend_xml(tree, os.path.join(args.configs, filename)) + start_timer(args.time) reg.loadElementTree(tree) end_timer(args.time, '* Time to parse ElementTree =') diff --git a/layer/trace_layer.cpp b/layer/trace_layer.cpp index 3df2c89d98..878d9015c5 100644 --- a/layer/trace_layer.cpp +++ b/layer/trace_layer.cpp @@ -70,6 +70,7 @@ const std::vector kDeviceExtensionProps = { "vkCmdDebugMarkerInsertEXT", "vkDebugMarkerSetObjectNameEXT", "vkDebugMarkerSetObjectTagEXT" } }, + { VkExtensionProperties{ "VK_ANDROID_frame_boundary", 1 }, {}, { "vkFrameBoundaryANDROID" } }, }; /// An alphabetical list of device extensions which we do not report upstream if