From 9c483c471a15f9d24c8365cfe002c017b83a55a8 Mon Sep 17 00:00:00 2001 From: Aitor Camacho Date: Tue, 3 Sep 2024 16:20:14 +0900 Subject: [PATCH 1/4] layers: Add VK_EXT_external_memory_metal --- layers/core_checks/cc_device_memory.cpp | 16 ++- layers/core_checks/cc_external_object.cpp | 130 ++++++++++++++++++ layers/core_checks/core_validation.h | 12 ++ layers/stateless/sl_external_object.cpp | 6 + layers/vulkan/generated/best_practices.cpp | 23 ++++ layers/vulkan/generated/best_practices.h | 10 ++ layers/vulkan/generated/chassis.cpp | 91 ++++++++++++ layers/vulkan/generated/chassis.h | 17 +++ .../generated/chassis_dispatch_helper.h | 14 ++ layers/vulkan/generated/enum_flag_bits.h | 2 +- .../generated/error_location_helper.cpp | 10 ++ .../vulkan/generated/error_location_helper.h | 8 ++ .../generated/layer_chassis_dispatch.cpp | 35 +++++ .../vulkan/generated/layer_chassis_dispatch.h | 7 + layers/vulkan/generated/object_tracker.cpp | 18 +++ layers/vulkan/generated/object_tracker.h | 4 + .../generated/pnext_chain_extraction.cpp | 7 + .../generated/stateless_validation_helper.cpp | 63 +++++++++ .../generated/stateless_validation_helper.h | 8 ++ layers/vulkan/generated/test_icd_helper.h | 29 ++++ layers/vulkan/generated/thread_safety.cpp | 26 ++++ .../vulkan/generated/thread_safety_commands.h | 18 +++ layers/vulkan/generated/valid_flag_values.cpp | 5 + .../generated/vk_dispatch_table_helper.cpp | 22 +++ .../vulkan/generated/vk_extension_helper.cpp | 1 + layers/vulkan/generated/vk_extension_helper.h | 7 + .../vulkan/generated/vk_function_pointers.cpp | 16 +++ .../vulkan/generated/vk_function_pointers.h | 4 + .../generated/vk_layer_dispatch_table.h | 4 + scripts/known_good.json | 8 +- 30 files changed, 615 insertions(+), 6 deletions(-) diff --git a/layers/core_checks/cc_device_memory.cpp b/layers/core_checks/cc_device_memory.cpp index a84ba712669..674ac54b648 100644 --- a/layers/core_checks/cc_device_memory.cpp +++ b/layers/core_checks/cc_device_memory.cpp @@ -344,7 +344,14 @@ bool CoreChecks::IgnoreAllocationSize(const VkMemoryAllocateInfo &allocate_info) if (import_memory_win32 && (import_memory_win32->handleType & ignored_allocation) != 0) { return true; } -#endif +#elif VK_USE_PLATFORM_METAL_EXT + const VkExternalMemoryHandleTypeFlags ignored_allocation = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT | + VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT; + const auto import_memory_metal = vku::FindStructInPNextChain(allocate_info.pNext); + if (import_memory_metal && (import_memory_metal->handleType & ignored_allocation) != 0) { + return true; + } +#endif // VK_USE_PLATFORM_METAL_EXT // Handles 01874 cases const auto export_info = vku::FindStructInPNextChain(allocate_info.pNext); if (export_info && (export_info->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) { @@ -756,6 +763,13 @@ bool CoreChecks::PreCallValidateAllocateMemory(VkDevice device, const VkMemoryAl } } #endif + +#ifdef VK_USE_PLATFORM_METAL_EXT + if (IsExtEnabled(device_extensions.vk_ext_external_memory_metal)) { + skip |= ValidateAllocateMemoryMetal(*pAllocateInfo, dedicated_allocate_info, allocate_info_loc); + } +#endif // VK_USE_PLATFORM_METAL_EXT + return skip; } diff --git a/layers/core_checks/cc_external_object.cpp b/layers/core_checks/cc_external_object.cpp index 538cd5089ab..d6050a2b685 100644 --- a/layers/core_checks/cc_external_object.cpp +++ b/layers/core_checks/cc_external_object.cpp @@ -549,3 +549,133 @@ bool CoreChecks::PreCallValidateExportMetalObjectsEXT(VkDevice device, VkExportM return skip; } #endif // VK_USE_PLATFORM_METAL_EXT + +bool CoreChecks::ValidateAllocateMemoryMetal(const VkMemoryAllocateInfo &allocate_info, + const VkMemoryDedicatedAllocateInfo *dedicated_allocation_info, + const Location &allocate_info_loc) const { + bool skip = false; + +#if VK_USE_PLATFORM_METAL_EXT + // When dealing with Metal external memory, we can have the following 3 scenarios: + // 1. Allocation will be exported. Contains VkExportMemoryAllocateInfo + // 2. Allocation is being imported. Contains VkImportMemoryMetalHandleInfoEXT + // 3. Previous 2 combined + // Whenever the memory will be used for an image, VK_EXT_external_memory_metal requires that the allocation + // is dedicated to that single resource. + + // Case 1 and partially 3 + if (const auto export_memory_info = vku::FindStructInPNextChain(allocate_info.pNext)) { + if ((export_memory_info->handleTypes == VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT) && dedicated_allocation_info == nullptr) { + skip |= LogError("VUID-UNASSIGNED-VK_EXT_external_memory-no-VkMemoryDedicatedAllocateInfo-export", device, + allocate_info_loc.dot(Field::pNext), + "VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT requires textures to be imported as a dedicated" + "allocation."); + } + } + + // Case 2 and remaining 3 + const auto import_memory_metal_info = vku::FindStructInPNextChain(allocate_info.pNext); + if (import_memory_metal_info == nullptr) { + return skip; + } + + // Ensure user is importing correct type before checking any other VUID since we will assume correct type + if ((import_memory_metal_info->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT) && + (import_memory_metal_info->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT)) { + skip |= LogError("VUID-VK_EXT_external_memory-incorrect-handle-type", device, + allocate_info_loc.dot(Struct::VkImportMemoryMetalHandleInfoEXT, Field::handleType), + "current value is %s", string_VkExternalMemoryHandleTypeFlagBits(import_memory_metal_info->handleType)); + return skip; + } + + // Only images require to be created as a dedicated allocation. This allows us to check if the format + // used by the image allows for importing such images from external memory. We cannot do that with + // buffers since we lack the usage, so it's not possible to know if the device allows import + // operations on buffers. + if(import_memory_metal_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT) { + if (dedicated_allocation_info == nullptr) { + skip |= LogError("VUID-UNASSIGNED-VK_EXT_external_memory-no-VkMemoryDedicatedAllocateInfo-import", device, + allocate_info_loc.dot(Field::pNext), + "VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT requires textures to be imported as a dedicated" + "allocation."); + // Early out since the image comes from VkMemoryDedicatedAllocateInfoKHR and there's none. + return skip; + } + + // Unsure if there should be a VUID that enforces image to not be NULL when importing a MTLTEXTURE type + if (dedicated_allocation_info->image == VK_NULL_HANDLE) { + skip |= LogError("VUID-UNASSIGNED-VK_EXT_external_memory-dedicated-null-image-import", device, + allocate_info_loc.dot(Struct::VkMemoryDedicatedAllocateInfo, Field::image), + "must be a valid image handle."); + // Early out since there's no image in VkMemoryDedicatedAllocateInfoKHR. + return skip; + } + + auto image_state_ptr = Get(dedicated_allocation_info->image); + VkFormat image_format = image_state_ptr->safe_create_info.format; + VkExternalImageFormatProperties external_image_format_properties; + external_image_format_properties.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES; + external_image_format_properties.pNext = nullptr; + VkFormatProperties2 format_properties; + format_properties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; + format_properties.pNext = &external_image_format_properties; + DispatchGetPhysicalDeviceFormatProperties2(physical_device, image_format, &format_properties); + + if ((external_image_format_properties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0u) { + skip |= LogError("VUID-UNASSIGNED-VK_EXT_external_memory-unsupported-format-import", device, + allocate_info_loc.dot(Struct::VkImportMemoryMetalHandleInfoEXT, Field::handleType), + "does not support importing image with format %s", string_VkFormat(image_format)); + } + } +#endif // VK_USE_PLATFORM_METAL_EXT + + return skip; +} + +#ifdef VK_USE_PLATFORM_METAL_EXT +bool CoreChecks::PreCallValidateGetMemoryMetalHandleEXT(VkDevice device, + const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, MTLResource_id* pHandle, + const ErrorObject& error_obj) const { + bool skip = false; + const Location get_metal_handle_info = error_obj.location.dot(Field::pGetMetalHandleInfo); + auto memory = Get(pGetMetalHandleInfo->memory); + ASSERT_AND_RETURN_SKIP(memory); + auto export_memory_allocate_info = vku::FindStructInPNextChain(memory->safe_allocate_info.pNext); + if (export_memory_allocate_info == nullptr) { + skip |= LogError("VUID-UNASSIGNED-VK_EXT_external_memory-memory-not-created-with-VkExportMemoryAllocateInfo", device, + get_metal_handle_info.dot(Field::memory).dot(Field::pNext), + "device memory missing VkExportMemoryAllocateInfo at creation"); + } + else if ((export_memory_allocate_info->handleTypes & pGetMetalHandleInfo->handleType) == 0u) { + skip |= LogError("VUID-VK_EXT_external_memory-memory-allocation-missing-handle-type", device, + get_metal_handle_info.dot(Field::handleType), + "device memory was created with (%s) handle types. Missing %s type", + string_VkExternalMemoryHandleTypeFlags(export_memory_allocate_info->handleTypes).c_str(), + string_VkExternalMemoryHandleTypeFlagBits(pGetMetalHandleInfo->handleType)); + } + + if ((pGetMetalHandleInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT) && + (pGetMetalHandleInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT)) { + skip |= LogError("VUID-VK_EXT_external_memory-get-handle-incorrect-handle-type", device, + get_metal_handle_info.dot(Field::handleType), + "current value is %s", string_VkExternalMemoryHandleTypeFlagBits(pGetMetalHandleInfo->handleType)); + } + return skip; +} + +bool CoreChecks::PreCallValidateGetMemoryMetalHandlePropertiesEXT(VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, + const ErrorObject& error_obj) const { + bool skip = false; + + if ((handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT) && + (handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT)) { + skip |= LogError("VUID-VK_EXT_external_memory-get-handle-incorrect-handle-type", device, + error_obj.location.dot(Field::handleType), + "current value is %s", string_VkExternalMemoryHandleTypeFlagBits(handleType)); + } + + return skip; +} +#endif // VK_USE_PLATFORM_METAL_EXT diff --git a/layers/core_checks/core_validation.h b/layers/core_checks/core_validation.h index ad79e8f28e7..a0eb7219b35 100644 --- a/layers/core_checks/core_validation.h +++ b/layers/core_checks/core_validation.h @@ -1196,6 +1196,9 @@ class CoreChecks : public ValidationStateTracker { bool ValidatePhysicalDeviceQueueFamilies(uint32_t queue_family_count, const uint32_t* queue_families, const Location& loc, const char* vuid) const; bool ValidateAllocateMemoryANDROID(const VkMemoryAllocateInfo& allocate_info, const Location& allocate_info_loc) const; + bool ValidateAllocateMemoryMetal(const VkMemoryAllocateInfo& allocate_info, + const VkMemoryDedicatedAllocateInfo *dedicated_allocation_info, + const Location& allocate_info_loc) const; bool ValidateGetImageMemoryRequirementsANDROID(const VkImage image, const Location& loc) const; bool ValidateGetPhysicalDeviceImageFormatProperties2ANDROID(const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, const VkImageFormatProperties2* pImageFormatProperties, @@ -1878,6 +1881,15 @@ class CoreChecks : public ValidationStateTracker { const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle, const RecordObject& record_obj) override; #endif +#ifdef VK_USE_PLATFORM_METAL_EXT + bool PreCallValidateGetMemoryMetalHandleEXT(VkDevice device, + const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, MTLResource_id* pHandle, + const ErrorObject& error_obj) const override; + bool PreCallValidateGetMemoryMetalHandlePropertiesEXT(VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, + const ErrorObject& error_obj) const override; +#endif // VK_USE_PLATFORM_METAL_EXT #ifdef VK_USE_PLATFORM_WIN32_KHR bool PreCallValidateGetMemoryWin32HandleKHR(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle, const ErrorObject& error_obj) const override; diff --git a/layers/stateless/sl_external_object.cpp b/layers/stateless/sl_external_object.cpp index bd69c32eba1..f5c47cf64eb 100644 --- a/layers/stateless/sl_external_object.cpp +++ b/layers/stateless/sl_external_object.cpp @@ -377,6 +377,12 @@ ExternalOperationsInfo GetExternalOperationsInfo(const void *pNext) { ext.total_import_ops += (import_info_qnx && import_info_qnx->buffer); #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + // VK_EXT_external_memory_metal + auto import_info_metal = vku::FindStructInPNextChain(pNext); + ext.total_import_ops += (import_info_metal && import_info_metal->handle); +#endif // VK_USE_PLATFORM_METAL_EXT + return ext; } } // namespace diff --git a/layers/vulkan/generated/best_practices.cpp b/layers/vulkan/generated/best_practices.cpp index 98ccc3c849b..bcf01a951bc 100644 --- a/layers/vulkan/generated/best_practices.cpp +++ b/layers/vulkan/generated/best_practices.cpp @@ -2994,6 +2994,29 @@ void BestPractices::PostCallRecordGetScreenBufferPropertiesQNX(VkDevice device, } #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +void BestPractices::PostCallRecordGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle, const RecordObject& record_obj) { + ValidationStateTracker::PostCallRecordGetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle, record_obj); + + if (record_obj.result < VK_SUCCESS) { + LogErrorCode(record_obj); + } +} + +void BestPractices::PostCallRecordGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, + const RecordObject& record_obj) { + ValidationStateTracker::PostCallRecordGetMemoryMetalHandlePropertiesEXT(device, handleType, handle, + pMemoryMetalHandleProperties, record_obj); + + if (record_obj.result < VK_SUCCESS) { + LogErrorCode(record_obj); + } +} +#endif // VK_USE_PLATFORM_METAL_EXT + void BestPractices::PostCallRecordCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, diff --git a/layers/vulkan/generated/best_practices.h b/layers/vulkan/generated/best_practices.h index 198fb19c24d..4ecf83b3221 100644 --- a/layers/vulkan/generated/best_practices.h +++ b/layers/vulkan/generated/best_practices.h @@ -982,6 +982,16 @@ void PostCallRecordGetScreenBufferPropertiesQNX(VkDevice device, const struct _s VkScreenBufferPropertiesQNX* pProperties, const RecordObject& record_obj) override; #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +void PostCallRecordGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle, const RecordObject& record_obj) override; + +void PostCallRecordGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, + const RecordObject& record_obj) override; + +#endif // VK_USE_PLATFORM_METAL_EXT void PostCallRecordCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure, diff --git a/layers/vulkan/generated/chassis.cpp b/layers/vulkan/generated/chassis.cpp index 2c29d96ce10..33c45badfac 100644 --- a/layers/vulkan/generated/chassis.cpp +++ b/layers/vulkan/generated/chassis.cpp @@ -26189,6 +26189,93 @@ VKAPI_ATTR VkResult VKAPI_CALL GetScreenBufferPropertiesQNX(VkDevice device, con } #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle) { + VVL_ZoneScoped; + + auto layer_data = GetLayerDataPtr(GetDispatchKey(device), layer_data_map); + bool skip = false; + ErrorObject error_obj(vvl::Func::vkGetMemoryMetalHandleEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice)); + { + VVL_ZoneScopedN("PreCallValidate"); + for (const ValidationObject* intercept : layer_data->intercept_vectors[InterceptIdPreCallValidateGetMemoryMetalHandleEXT]) { + auto lock = intercept->ReadLock(); + skip |= intercept->PreCallValidateGetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle, error_obj); + if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; + } + } + RecordObject record_obj(vvl::Func::vkGetMemoryMetalHandleEXT); + { + VVL_ZoneScopedN("PreCallRecord"); + for (ValidationObject* intercept : layer_data->intercept_vectors[InterceptIdPreCallRecordGetMemoryMetalHandleEXT]) { + auto lock = intercept->WriteLock(); + intercept->PreCallRecordGetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle, record_obj); + } + } + VkResult result; + { + VVL_ZoneScopedN("Dispatch"); + result = DispatchGetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle); + } + record_obj.result = result; + { + VVL_ZoneScopedN("PostCallRecord"); + for (ValidationObject* intercept : layer_data->intercept_vectors[InterceptIdPostCallRecordGetMemoryMetalHandleEXT]) { + auto lock = intercept->WriteLock(); + intercept->PostCallRecordGetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle, record_obj); + } + } + return result; +} + +VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties) { + VVL_ZoneScoped; + + auto layer_data = GetLayerDataPtr(GetDispatchKey(device), layer_data_map); + bool skip = false; + ErrorObject error_obj(vvl::Func::vkGetMemoryMetalHandlePropertiesEXT, VulkanTypedHandle(device, kVulkanObjectTypeDevice)); + { + VVL_ZoneScopedN("PreCallValidate"); + for (const ValidationObject* intercept : + layer_data->intercept_vectors[InterceptIdPreCallValidateGetMemoryMetalHandlePropertiesEXT]) { + auto lock = intercept->ReadLock(); + skip |= intercept->PreCallValidateGetMemoryMetalHandlePropertiesEXT(device, handleType, handle, + pMemoryMetalHandleProperties, error_obj); + if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; + } + } + RecordObject record_obj(vvl::Func::vkGetMemoryMetalHandlePropertiesEXT); + { + VVL_ZoneScopedN("PreCallRecord"); + for (ValidationObject* intercept : + layer_data->intercept_vectors[InterceptIdPreCallRecordGetMemoryMetalHandlePropertiesEXT]) { + auto lock = intercept->WriteLock(); + intercept->PreCallRecordGetMemoryMetalHandlePropertiesEXT(device, handleType, handle, pMemoryMetalHandleProperties, + record_obj); + } + } + VkResult result; + { + VVL_ZoneScopedN("Dispatch"); + result = DispatchGetMemoryMetalHandlePropertiesEXT(device, handleType, handle, pMemoryMetalHandleProperties); + } + record_obj.result = result; + { + VVL_ZoneScopedN("PostCallRecord"); + for (ValidationObject* intercept : + layer_data->intercept_vectors[InterceptIdPostCallRecordGetMemoryMetalHandlePropertiesEXT]) { + auto lock = intercept->WriteLock(); + intercept->PostCallRecordGetMemoryMetalHandlePropertiesEXT(device, handleType, handle, pMemoryMetalHandleProperties, + record_obj); + } + } + return result; +} + +#endif // VK_USE_PLATFORM_METAL_EXT VKAPI_ATTR VkResult VKAPI_CALL CreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, @@ -27933,6 +28020,10 @@ const vvl::unordered_map &GetNameToFuncPtrMap() { #ifdef VK_USE_PLATFORM_SCREEN_QNX {"vkGetScreenBufferPropertiesQNX", {kFuncTypeDev, (void*)GetScreenBufferPropertiesQNX}}, #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + {"vkGetMemoryMetalHandleEXT", {kFuncTypeDev, (void*)GetMemoryMetalHandleEXT}}, + {"vkGetMemoryMetalHandlePropertiesEXT", {kFuncTypeDev, (void*)GetMemoryMetalHandlePropertiesEXT}}, +#endif // VK_USE_PLATFORM_METAL_EXT {"vkCreateAccelerationStructureKHR", {kFuncTypeDev, (void*)CreateAccelerationStructureKHR}}, {"vkDestroyAccelerationStructureKHR", {kFuncTypeDev, (void*)DestroyAccelerationStructureKHR}}, {"vkCmdBuildAccelerationStructuresKHR", {kFuncTypeDev, (void*)CmdBuildAccelerationStructuresKHR}}, diff --git a/layers/vulkan/generated/chassis.h b/layers/vulkan/generated/chassis.h index a06769b6547..4dc557e190d 100644 --- a/layers/vulkan/generated/chassis.h +++ b/layers/vulkan/generated/chassis.h @@ -2070,6 +2070,15 @@ VKAPI_ATTR VkResult VKAPI_CALL GetScreenBufferPropertiesQNX(VkDevice device, con VkScreenBufferPropertiesQNX* pProperties); #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle); + +VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties); + +#endif // VK_USE_PLATFORM_METAL_EXT VKAPI_ATTR VkResult VKAPI_CALL CreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, @@ -4452,6 +4461,14 @@ class ValidationObject { virtual void PreCallRecordGetScreenBufferPropertiesQNX(VkDevice device, const struct _screen_buffer* buffer, VkScreenBufferPropertiesQNX* pProperties, const RecordObject& record_obj) {}; virtual void PostCallRecordGetScreenBufferPropertiesQNX(VkDevice device, const struct _screen_buffer* buffer, VkScreenBufferPropertiesQNX* pProperties, const RecordObject& record_obj) {}; #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + virtual bool PreCallValidateGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, MTLResource_id* pHandle, const ErrorObject& error_obj) const { return false; }; + virtual void PreCallRecordGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, MTLResource_id* pHandle, const RecordObject& record_obj) {}; + virtual void PostCallRecordGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, MTLResource_id* pHandle, const RecordObject& record_obj) {}; + virtual bool PreCallValidateGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, MTLResource_id handle, VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, const ErrorObject& error_obj) const { return false; }; + virtual void PreCallRecordGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, MTLResource_id handle, VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, const RecordObject& record_obj) {}; + virtual void PostCallRecordGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, MTLResource_id handle, VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, const RecordObject& record_obj) {}; +#endif // VK_USE_PLATFORM_METAL_EXT virtual bool PreCallValidateCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure, const ErrorObject& error_obj) const { return false; }; virtual void PreCallRecordCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure, const RecordObject& record_obj) {}; virtual void PostCallRecordCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure, const RecordObject& record_obj) {}; diff --git a/layers/vulkan/generated/chassis_dispatch_helper.h b/layers/vulkan/generated/chassis_dispatch_helper.h index 76fd181b4ec..a1c4e9352e5 100644 --- a/layers/vulkan/generated/chassis_dispatch_helper.h +++ b/layers/vulkan/generated/chassis_dispatch_helper.h @@ -1637,6 +1637,12 @@ typedef enum InterceptId { InterceptIdPreCallValidateGetScreenBufferPropertiesQNX, InterceptIdPreCallRecordGetScreenBufferPropertiesQNX, InterceptIdPostCallRecordGetScreenBufferPropertiesQNX, + InterceptIdPreCallValidateGetMemoryMetalHandleEXT, + InterceptIdPreCallRecordGetMemoryMetalHandleEXT, + InterceptIdPostCallRecordGetMemoryMetalHandleEXT, + InterceptIdPreCallValidateGetMemoryMetalHandlePropertiesEXT, + InterceptIdPreCallRecordGetMemoryMetalHandlePropertiesEXT, + InterceptIdPostCallRecordGetMemoryMetalHandlePropertiesEXT, InterceptIdPreCallValidateCreateAccelerationStructureKHR, InterceptIdPreCallRecordCreateAccelerationStructureKHR, InterceptIdPostCallRecordCreateAccelerationStructureKHR, @@ -3400,6 +3406,14 @@ void ValidationObject::InitObjectDispatchVectors() { BUILD_DISPATCH_VECTOR(PreCallRecordGetScreenBufferPropertiesQNX); BUILD_DISPATCH_VECTOR(PostCallRecordGetScreenBufferPropertiesQNX); #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + BUILD_DISPATCH_VECTOR(PreCallValidateGetMemoryMetalHandleEXT); + BUILD_DISPATCH_VECTOR(PreCallRecordGetMemoryMetalHandleEXT); + BUILD_DISPATCH_VECTOR(PostCallRecordGetMemoryMetalHandleEXT); + BUILD_DISPATCH_VECTOR(PreCallValidateGetMemoryMetalHandlePropertiesEXT); + BUILD_DISPATCH_VECTOR(PreCallRecordGetMemoryMetalHandlePropertiesEXT); + BUILD_DISPATCH_VECTOR(PostCallRecordGetMemoryMetalHandlePropertiesEXT); +#endif // VK_USE_PLATFORM_METAL_EXT BUILD_DISPATCH_VECTOR(PreCallValidateCreateAccelerationStructureKHR); BUILD_DISPATCH_VECTOR(PreCallRecordCreateAccelerationStructureKHR); BUILD_DISPATCH_VECTOR(PostCallRecordCreateAccelerationStructureKHR); diff --git a/layers/vulkan/generated/enum_flag_bits.h b/layers/vulkan/generated/enum_flag_bits.h index 5c8cba6bc33..fc7d9407569 100644 --- a/layers/vulkan/generated/enum_flag_bits.h +++ b/layers/vulkan/generated/enum_flag_bits.h @@ -60,7 +60,7 @@ const VkCommandPoolCreateFlags AllVkCommandPoolCreateFlagBits = VK_COMMAND_POOL_ const VkQueryControlFlags AllVkQueryControlFlagBits = VK_QUERY_CONTROL_PRECISE_BIT; const VkCommandBufferUsageFlags AllVkCommandBufferUsageFlagBits = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT|VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT|VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; const VkMemoryAllocateFlags AllVkMemoryAllocateFlagBits = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT|VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT|VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT; -const VkExternalMemoryHandleTypeFlags AllVkExternalMemoryHandleTypeFlagBits = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID|VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA|VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV|VK_EXTERNAL_MEMORY_HANDLE_TYPE_SCREEN_BUFFER_BIT_QNX; +const VkExternalMemoryHandleTypeFlags AllVkExternalMemoryHandleTypeFlagBits = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID|VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA|VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV|VK_EXTERNAL_MEMORY_HANDLE_TYPE_SCREEN_BUFFER_BIT_QNX|VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT|VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT; const VkExternalFenceHandleTypeFlags AllVkExternalFenceHandleTypeFlagBits = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT|VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT|VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT|VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT; const VkExternalSemaphoreHandleTypeFlags AllVkExternalSemaphoreHandleTypeFlagBits = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT|VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT|VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT|VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT|VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT|VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA; const VkDescriptorBindingFlags AllVkDescriptorBindingFlagBits = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT|VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT|VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT|VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT; diff --git a/layers/vulkan/generated/error_location_helper.cpp b/layers/vulkan/generated/error_location_helper.cpp index ec78f76ad42..a96481eff79 100644 --- a/layers/vulkan/generated/error_location_helper.cpp +++ b/layers/vulkan/generated/error_location_helper.cpp @@ -538,6 +538,8 @@ const char* String(Func func) { {"vkGetMemoryFdKHR", 17}, {"vkGetMemoryFdPropertiesKHR", 27}, {"vkGetMemoryHostPointerPropertiesEXT", 36}, + {"vkGetMemoryMetalHandleEXT", 26}, + {"vkGetMemoryMetalHandlePropertiesEXT", 36}, {"vkGetMemoryRemoteAddressNV", 27}, {"vkGetMemoryWin32HandleKHR", 26}, {"vkGetMemoryWin32HandleNV", 25}, @@ -1067,6 +1069,7 @@ const char* String(Struct structure) { {"VkImportMemoryBufferCollectionFUCHSIA", 38}, {"VkImportMemoryFdInfoKHR", 24}, {"VkImportMemoryHostPointerInfoEXT", 33}, + {"VkImportMemoryMetalHandleInfoEXT", 33}, {"VkImportMemoryWin32HandleInfoKHR", 33}, {"VkImportMemoryWin32HandleInfoNV", 32}, {"VkImportMemoryZirconHandleInfoFUCHSIA", 38}, @@ -1103,6 +1106,7 @@ const char* String(Struct structure) { {"VkMemoryFdPropertiesKHR", 24}, {"VkMemoryGetAndroidHardwareBufferInfoANDROID", 44}, {"VkMemoryGetFdInfoKHR", 21}, + {"VkMemoryGetMetalHandleInfoEXT", 30}, {"VkMemoryGetRemoteAddressInfoNV", 31}, {"VkMemoryGetWin32HandleInfoKHR", 30}, {"VkMemoryGetZirconHandleInfoFUCHSIA", 35}, @@ -1110,6 +1114,7 @@ const char* String(Struct structure) { {"VkMemoryHostPointerPropertiesEXT", 33}, {"VkMemoryMapInfoKHR", 19}, {"VkMemoryMapPlacedInfoEXT", 25}, + {"VkMemoryMetalHandlePropertiesEXT", 33}, {"VkMemoryOpaqueCaptureAddressAllocateInfo", 41}, {"VkMemoryPriorityAllocateInfoEXT", 32}, {"VkMemoryRequirements", 21}, @@ -3260,6 +3265,7 @@ const char* String(Field field) { {"pGeneratedCommandsInfo", 23}, {"pGeometries", 12}, {"pGetFdInfo", 11}, + {"pGetMetalHandleInfo", 20}, {"pGetWin32HandleInfo", 20}, {"pGetZirconHandleInfo", 21}, {"pGranularity", 13}, @@ -3333,6 +3339,7 @@ const char* String(Field field) { {"pMemoryGetRemoteAddressInfo", 28}, {"pMemoryHostPointerProperties", 29}, {"pMemoryMapInfo", 15}, + {"pMemoryMetalHandleProperties", 29}, {"pMemoryProperties", 18}, {"pMemoryRanges", 14}, {"pMemoryRequirements", 20}, @@ -4770,6 +4777,7 @@ const char* String(Extension extension) { {"VK_EXT_external_memory_acquire_unmodified", 42}, {"VK_EXT_external_memory_dma_buf", 31}, {"VK_EXT_external_memory_host", 28}, + {"VK_EXT_external_memory_metal", 29}, {"VK_EXT_filter_cubic", 20}, {"VK_EXT_fragment_density_map", 28}, {"VK_EXT_fragment_density_map2", 29}, @@ -5279,6 +5287,7 @@ bool IsFieldPointer(Field field) { case Field::pGeneratedCommandsInfo: case Field::pGeometries: case Field::pGetFdInfo: + case Field::pGetMetalHandleInfo: case Field::pGetWin32HandleInfo: case Field::pGetZirconHandleInfo: case Field::pGranularity: @@ -5352,6 +5361,7 @@ bool IsFieldPointer(Field field) { case Field::pMemoryGetRemoteAddressInfo: case Field::pMemoryHostPointerProperties: case Field::pMemoryMapInfo: + case Field::pMemoryMetalHandleProperties: case Field::pMemoryProperties: case Field::pMemoryRanges: case Field::pMemoryRequirements: diff --git a/layers/vulkan/generated/error_location_helper.h b/layers/vulkan/generated/error_location_helper.h index 83d9de655ef..c301b2ca839 100644 --- a/layers/vulkan/generated/error_location_helper.h +++ b/layers/vulkan/generated/error_location_helper.h @@ -537,6 +537,8 @@ enum class Func { vkGetMemoryFdKHR, vkGetMemoryFdPropertiesKHR, vkGetMemoryHostPointerPropertiesEXT, + vkGetMemoryMetalHandleEXT, + vkGetMemoryMetalHandlePropertiesEXT, vkGetMemoryRemoteAddressNV, vkGetMemoryWin32HandleKHR, vkGetMemoryWin32HandleNV, @@ -1063,6 +1065,7 @@ enum class Struct { VkImportMemoryBufferCollectionFUCHSIA, VkImportMemoryFdInfoKHR, VkImportMemoryHostPointerInfoEXT, + VkImportMemoryMetalHandleInfoEXT, VkImportMemoryWin32HandleInfoKHR, VkImportMemoryWin32HandleInfoNV, VkImportMemoryZirconHandleInfoFUCHSIA, @@ -1099,6 +1102,7 @@ enum class Struct { VkMemoryFdPropertiesKHR, VkMemoryGetAndroidHardwareBufferInfoANDROID, VkMemoryGetFdInfoKHR, + VkMemoryGetMetalHandleInfoEXT, VkMemoryGetRemoteAddressInfoNV, VkMemoryGetWin32HandleInfoKHR, VkMemoryGetZirconHandleInfoFUCHSIA, @@ -1106,6 +1110,7 @@ enum class Struct { VkMemoryHostPointerPropertiesEXT, VkMemoryMapInfoKHR, VkMemoryMapPlacedInfoEXT, + VkMemoryMetalHandlePropertiesEXT, VkMemoryOpaqueCaptureAddressAllocateInfo, VkMemoryPriorityAllocateInfoEXT, VkMemoryRequirements, @@ -3253,6 +3258,7 @@ enum class Field { pGeneratedCommandsInfo, pGeometries, pGetFdInfo, + pGetMetalHandleInfo, pGetWin32HandleInfo, pGetZirconHandleInfo, pGranularity, @@ -3326,6 +3332,7 @@ enum class Field { pMemoryGetRemoteAddressInfo, pMemoryHostPointerProperties, pMemoryMapInfo, + pMemoryMetalHandleProperties, pMemoryProperties, pMemoryRanges, pMemoryRequirements, @@ -4754,6 +4761,7 @@ enum class Extension { _VK_EXT_external_memory_acquire_unmodified, _VK_EXT_external_memory_dma_buf, _VK_EXT_external_memory_host, + _VK_EXT_external_memory_metal, _VK_EXT_filter_cubic, _VK_EXT_fragment_density_map, _VK_EXT_fragment_density_map2, diff --git a/layers/vulkan/generated/layer_chassis_dispatch.cpp b/layers/vulkan/generated/layer_chassis_dispatch.cpp index 0df4bf0e9ba..e07cd6e1111 100644 --- a/layers/vulkan/generated/layer_chassis_dispatch.cpp +++ b/layers/vulkan/generated/layer_chassis_dispatch.cpp @@ -8915,6 +8915,41 @@ VkResult DispatchGetScreenBufferPropertiesQNX(VkDevice device, const struct _scr return result; } #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + +VkResult DispatchGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle) { + auto layer_data = GetLayerDataPtr(GetDispatchKey(device), layer_data_map); + if (!wrap_handles) return layer_data->device_dispatch_table.GetMemoryMetalHandleEXT(device, pGetMetalHandleInfo, pHandle); + vku::safe_VkMemoryGetMetalHandleInfoEXT var_local_pGetMetalHandleInfo; + vku::safe_VkMemoryGetMetalHandleInfoEXT* local_pGetMetalHandleInfo = nullptr; + { + if (pGetMetalHandleInfo) { + local_pGetMetalHandleInfo = &var_local_pGetMetalHandleInfo; + local_pGetMetalHandleInfo->initialize(pGetMetalHandleInfo); + + if (pGetMetalHandleInfo->memory) { + local_pGetMetalHandleInfo->memory = layer_data->Unwrap(pGetMetalHandleInfo->memory); + } + } + } + VkResult result = layer_data->device_dispatch_table.GetMemoryMetalHandleEXT( + device, (const VkMemoryGetMetalHandleInfoEXT*)local_pGetMetalHandleInfo, pHandle); + + return result; +} + +VkResult DispatchGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties) { + auto layer_data = GetLayerDataPtr(GetDispatchKey(device), layer_data_map); + + VkResult result = layer_data->device_dispatch_table.GetMemoryMetalHandlePropertiesEXT(device, handleType, handle, + pMemoryMetalHandleProperties); + + return result; +} +#endif // VK_USE_PLATFORM_METAL_EXT VkResult DispatchCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, diff --git a/layers/vulkan/generated/layer_chassis_dispatch.h b/layers/vulkan/generated/layer_chassis_dispatch.h index d0e36a0b68a..23d003f2b56 100644 --- a/layers/vulkan/generated/layer_chassis_dispatch.h +++ b/layers/vulkan/generated/layer_chassis_dispatch.h @@ -1171,6 +1171,13 @@ void DispatchCmdSetAttachmentFeedbackLoopEnableEXT(VkCommandBuffer commandBuffer VkResult DispatchGetScreenBufferPropertiesQNX(VkDevice device, const struct _screen_buffer* buffer, VkScreenBufferPropertiesQNX* pProperties); #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +VkResult DispatchGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle); +VkResult DispatchGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties); +#endif // VK_USE_PLATFORM_METAL_EXT VkResult DispatchCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure); diff --git a/layers/vulkan/generated/object_tracker.cpp b/layers/vulkan/generated/object_tracker.cpp index 55fc5f01146..1341b9cc080 100644 --- a/layers/vulkan/generated/object_tracker.cpp +++ b/layers/vulkan/generated/object_tracker.cpp @@ -7525,6 +7525,24 @@ bool ObjectLifetimes::PreCallValidateGetLatencyTimingsNV(VkDevice device, VkSwap // Checked by chassis: device: "VUID-vkGetScreenBufferPropertiesQNX-device-parameter" #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + +bool ObjectLifetimes::PreCallValidateGetMemoryMetalHandleEXT(VkDevice device, + const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle, const ErrorObject& error_obj) const { + bool skip = false; + // Checked by chassis: device: kVUIDUndefined + if (pGetMetalHandleInfo) { + [[maybe_unused]] const Location pGetMetalHandleInfo_loc = error_obj.location.dot(Field::pGetMetalHandleInfo); + } + + return skip; +} + +// vkGetMemoryMetalHandlePropertiesEXT: +// Checked by chassis: device: kVUIDUndefined + +#endif // VK_USE_PLATFORM_METAL_EXT bool ObjectLifetimes::PreCallValidateCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, diff --git a/layers/vulkan/generated/object_tracker.h b/layers/vulkan/generated/object_tracker.h index f1ce26494a3..dbcca95827e 100644 --- a/layers/vulkan/generated/object_tracker.h +++ b/layers/vulkan/generated/object_tracker.h @@ -1367,6 +1367,10 @@ bool PreCallValidateGetLatencyTimingsNV(VkDevice device, VkSwapchainKHR swapchai const ErrorObject& error_obj) const override; #ifdef VK_USE_PLATFORM_SCREEN_QNX #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +bool PreCallValidateGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle, const ErrorObject& error_obj) const override; +#endif // VK_USE_PLATFORM_METAL_EXT bool PreCallValidateCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure, diff --git a/layers/vulkan/generated/pnext_chain_extraction.cpp b/layers/vulkan/generated/pnext_chain_extraction.cpp index 66b2c0f031f..369fa0c7083 100644 --- a/layers/vulkan/generated/pnext_chain_extraction.cpp +++ b/layers/vulkan/generated/pnext_chain_extraction.cpp @@ -2983,6 +2983,13 @@ void PnextChainFree(void *chain) { header->pNext = nullptr; delete reinterpret_cast(header); break; +#ifdef VK_USE_PLATFORM_METAL_EXT + case VK_STRUCTURE_TYPE_IMPORT_MEMORY_METAL_HANDLE_INFO_EXT: + PnextChainFree(header->pNext); + header->pNext = nullptr; + delete reinterpret_cast(header); + break; +#endif // VK_USE_PLATFORM_METAL_EXT case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR: PnextChainFree(header->pNext); header->pNext = nullptr; diff --git a/layers/vulkan/generated/stateless_validation_helper.cpp b/layers/vulkan/generated/stateless_validation_helper.cpp index 97e9315f459..6ba39260beb 100644 --- a/layers/vulkan/generated/stateless_validation_helper.cpp +++ b/layers/vulkan/generated/stateless_validation_helper.cpp @@ -9447,6 +9447,23 @@ bool StatelessValidation::ValidatePnextStructContents(const Location& loc, const // No Validation code for VkImageAlignmentControlCreateInfoMESA structure members -- Covers // VUID-VkImageAlignmentControlCreateInfoMESA-sType-sType +#ifdef VK_USE_PLATFORM_METAL_EXT + + // Validation code for VkImportMemoryMetalHandleInfoEXT structure members + case VK_STRUCTURE_TYPE_IMPORT_MEMORY_METAL_HANDLE_INFO_EXT: { // Covers VUID-VkImportMemoryMetalHandleInfoEXT-sType-sType + if (is_const_param) { + [[maybe_unused]] const Location pNext_loc = loc.pNext(Struct::VkImportMemoryMetalHandleInfoEXT); + if (!IsExtEnabled(device_extensions.vk_ext_external_memory_metal)) { + skip |= LogError(pnext_vuid, instance, pNext_loc, + "extended struct requires the extensions VK_EXT_external_memory_metal"); + } + VkImportMemoryMetalHandleInfoEXT* structure = (VkImportMemoryMetalHandleInfoEXT*)header; + skip |= + ValidateFlags(pNext_loc.dot(Field::handleType), vvl::FlagBitmask::VkExternalMemoryHandleTypeFlagBits, + AllVkExternalMemoryHandleTypeFlagBits, structure->handleType, kOptionalSingleBit, kVUIDUndefined); + } + } break; +#endif // VK_USE_PLATFORM_METAL_EXT // Validation code for VkWriteDescriptorSetAccelerationStructureKHR structure members case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR: { // Covers @@ -10177,6 +10194,7 @@ bool StatelessValidation::PreCallValidateAllocateMemory(VkDevice device, const V VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA, VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_METAL_HANDLE_INFO_EXT, VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV, VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA, @@ -25826,6 +25844,51 @@ bool StatelessValidation::PreCallValidateGetScreenBufferPropertiesQNX(VkDevice d } #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +bool StatelessValidation::PreCallValidateGetMemoryMetalHandleEXT(VkDevice device, + const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle, const ErrorObject& error_obj) const { + bool skip = false; + [[maybe_unused]] const Location loc = error_obj.location; + if (!IsExtEnabled(device_extensions.vk_ext_external_memory_metal)) + skip |= OutputExtensionError(loc, {vvl::Extension::_VK_EXT_external_memory_metal}); + skip |= ValidateStructType(loc.dot(Field::pGetMetalHandleInfo), pGetMetalHandleInfo, + VK_STRUCTURE_TYPE_MEMORY_GET_METAL_HANDLE_INFO_EXT, true, kVUIDUndefined, kVUIDUndefined); + if (pGetMetalHandleInfo != nullptr) { + [[maybe_unused]] const Location pGetMetalHandleInfo_loc = loc.dot(Field::pGetMetalHandleInfo); + skip |= ValidateStructPnext(pGetMetalHandleInfo_loc, pGetMetalHandleInfo->pNext, 0, nullptr, GeneratedVulkanHeaderVersion, + kVUIDUndefined, kVUIDUndefined, VK_NULL_HANDLE, true); + + skip |= ValidateRequiredHandle(pGetMetalHandleInfo_loc.dot(Field::memory), pGetMetalHandleInfo->memory); + + skip |= ValidateFlags(pGetMetalHandleInfo_loc.dot(Field::handleType), vvl::FlagBitmask::VkExternalMemoryHandleTypeFlagBits, + AllVkExternalMemoryHandleTypeFlagBits, pGetMetalHandleInfo->handleType, kRequiredSingleBit, + kVUIDUndefined, kVUIDUndefined); + } + skip |= ValidateRequiredPointer(loc.dot(Field::pHandle), pHandle, kVUIDUndefined); + return skip; +} + +bool StatelessValidation::PreCallValidateGetMemoryMetalHandlePropertiesEXT( + VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, const ErrorObject& error_obj) const { + bool skip = false; + [[maybe_unused]] const Location loc = error_obj.location; + if (!IsExtEnabled(device_extensions.vk_ext_external_memory_metal)) + skip |= OutputExtensionError(loc, {vvl::Extension::_VK_EXT_external_memory_metal}); + skip |= ValidateFlags(loc.dot(Field::handleType), vvl::FlagBitmask::VkExternalMemoryHandleTypeFlagBits, + AllVkExternalMemoryHandleTypeFlagBits, handleType, kRequiredSingleBit, kVUIDUndefined, kVUIDUndefined); + skip |= ValidateStructType(loc.dot(Field::pMemoryMetalHandleProperties), pMemoryMetalHandleProperties, + VK_STRUCTURE_TYPE_MEMORY_METAL_HANDLE_PROPERTIES_EXT, true, kVUIDUndefined, kVUIDUndefined); + if (pMemoryMetalHandleProperties != nullptr) { + [[maybe_unused]] const Location pMemoryMetalHandleProperties_loc = loc.dot(Field::pMemoryMetalHandleProperties); + skip |= ValidateStructPnext(pMemoryMetalHandleProperties_loc, pMemoryMetalHandleProperties->pNext, 0, nullptr, + GeneratedVulkanHeaderVersion, kVUIDUndefined, kVUIDUndefined, VK_NULL_HANDLE, false); + } + return skip; +} +#endif // VK_USE_PLATFORM_METAL_EXT + bool StatelessValidation::PreCallValidateCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, diff --git a/layers/vulkan/generated/stateless_validation_helper.h b/layers/vulkan/generated/stateless_validation_helper.h index e85bbfeafb3..9e461c4238e 100644 --- a/layers/vulkan/generated/stateless_validation_helper.h +++ b/layers/vulkan/generated/stateless_validation_helper.h @@ -1731,6 +1731,14 @@ bool PreCallValidateGetScreenBufferPropertiesQNX(VkDevice device, const struct _ VkScreenBufferPropertiesQNX* pProperties, const ErrorObject& error_obj) const override; #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +bool PreCallValidateGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle, const ErrorObject& error_obj) const override; +bool PreCallValidateGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, + const ErrorObject& error_obj) const override; +#endif // VK_USE_PLATFORM_METAL_EXT bool PreCallValidateCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure, diff --git a/layers/vulkan/generated/test_icd_helper.h b/layers/vulkan/generated/test_icd_helper.h index 64437427ad5..703189cc1e7 100644 --- a/layers/vulkan/generated/test_icd_helper.h +++ b/layers/vulkan/generated/test_icd_helper.h @@ -470,6 +470,9 @@ static const std::unordered_map device_extension_map = { {VK_EXT_SHADER_REPLICATED_COMPOSITES_EXTENSION_NAME, VK_EXT_SHADER_REPLICATED_COMPOSITES_SPEC_VERSION}, {VK_NV_RAY_TRACING_VALIDATION_EXTENSION_NAME, VK_NV_RAY_TRACING_VALIDATION_SPEC_VERSION}, {VK_MESA_IMAGE_ALIGNMENT_CONTROL_EXTENSION_NAME, VK_MESA_IMAGE_ALIGNMENT_CONTROL_SPEC_VERSION}, +#ifdef VK_USE_PLATFORM_METAL_EXT + {VK_EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME, VK_EXT_EXTERNAL_MEMORY_METAL_SPEC_VERSION}, +#endif // VK_USE_PLATFORM_METAL_EXT {VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION}, {VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, VK_KHR_RAY_TRACING_PIPELINE_SPEC_VERSION}, {VK_KHR_RAY_QUERY_EXTENSION_NAME, VK_KHR_RAY_QUERY_SPEC_VERSION}, @@ -1899,6 +1902,14 @@ static VKAPI_ATTR void VKAPI_CALL CmdSetAttachmentFeedbackLoopEnableEXT(VkComman static VKAPI_ATTR VkResult VKAPI_CALL GetScreenBufferPropertiesQNX(VkDevice device, const struct _screen_buffer* buffer, VkScreenBufferPropertiesQNX* pProperties); #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +static VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandleEXT(VkDevice device, + const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle); +static VKAPI_ATTR VkResult VKAPI_CALL +GetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties); +#endif // VK_USE_PLATFORM_METAL_EXT static VKAPI_ATTR VkResult VKAPI_CALL CreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, @@ -2684,6 +2695,10 @@ static const std::unordered_map name_to_func_ptr_map = { #ifdef VK_USE_PLATFORM_SCREEN_QNX {"vkGetScreenBufferPropertiesQNX", (void*)GetScreenBufferPropertiesQNX}, #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + {"vkGetMemoryMetalHandleEXT", (void*)GetMemoryMetalHandleEXT}, + {"vkGetMemoryMetalHandlePropertiesEXT", (void*)GetMemoryMetalHandlePropertiesEXT}, +#endif // VK_USE_PLATFORM_METAL_EXT {"vkCreateAccelerationStructureKHR", (void*)CreateAccelerationStructureKHR}, {"vkDestroyAccelerationStructureKHR", (void*)DestroyAccelerationStructureKHR}, {"vkCmdBuildAccelerationStructuresKHR", (void*)CmdBuildAccelerationStructuresKHR}, @@ -5219,6 +5234,20 @@ static VKAPI_ATTR VkResult VKAPI_CALL GetScreenBufferPropertiesQNX(VkDevice devi } #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +static VKAPI_ATTR VkResult VKAPI_CALL GetMemoryMetalHandleEXT(VkDevice device, + const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle) { + return VK_SUCCESS; +} + +static VKAPI_ATTR VkResult VKAPI_CALL +GetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties) { + return VK_SUCCESS; +} + +#endif // VK_USE_PLATFORM_METAL_EXT static VKAPI_ATTR VkResult VKAPI_CALL CreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, diff --git a/layers/vulkan/generated/thread_safety.cpp b/layers/vulkan/generated/thread_safety.cpp index 5a624963a49..9cfc6808fe8 100644 --- a/layers/vulkan/generated/thread_safety.cpp +++ b/layers/vulkan/generated/thread_safety.cpp @@ -7814,6 +7814,32 @@ void ThreadSafety::PostCallRecordGetScreenBufferPropertiesQNX(VkDevice device, c } #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +void ThreadSafety::PreCallRecordGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle, const RecordObject& record_obj) { + StartReadObjectParentInstance(device, record_obj.location); +} + +void ThreadSafety::PostCallRecordGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle, const RecordObject& record_obj) { + FinishReadObjectParentInstance(device, record_obj.location); +} + +void ThreadSafety::PreCallRecordGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, + const RecordObject& record_obj) { + StartReadObjectParentInstance(device, record_obj.location); +} + +void ThreadSafety::PostCallRecordGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, + const RecordObject& record_obj) { + FinishReadObjectParentInstance(device, record_obj.location); +} + +#endif // VK_USE_PLATFORM_METAL_EXT void ThreadSafety::PreCallRecordCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, diff --git a/layers/vulkan/generated/thread_safety_commands.h b/layers/vulkan/generated/thread_safety_commands.h index 45773b451ab..6f16ce086eb 100644 --- a/layers/vulkan/generated/thread_safety_commands.h +++ b/layers/vulkan/generated/thread_safety_commands.h @@ -4003,6 +4003,24 @@ void PostCallRecordGetScreenBufferPropertiesQNX(VkDevice device, const struct _s VkScreenBufferPropertiesQNX* pProperties, const RecordObject& record_obj) override; #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +void PreCallRecordGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle, const RecordObject& record_obj) override; + +void PostCallRecordGetMemoryMetalHandleEXT(VkDevice device, const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle, const RecordObject& record_obj) override; + +void PreCallRecordGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, + const RecordObject& record_obj) override; + +void PostCallRecordGetMemoryMetalHandlePropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties, + const RecordObject& record_obj) override; + +#endif // VK_USE_PLATFORM_METAL_EXT void PreCallRecordCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure, diff --git a/layers/vulkan/generated/valid_flag_values.cpp b/layers/vulkan/generated/valid_flag_values.cpp index 4131d695161..c262bce58e8 100644 --- a/layers/vulkan/generated/valid_flag_values.cpp +++ b/layers/vulkan/generated/valid_flag_values.cpp @@ -766,6 +766,11 @@ vvl::Extensions StatelessValidation::IsValidFlagValue(vvl::FlagBitmask flag_bitm return {vvl::Extension::_VK_QNX_external_memory_screen_buffer}; } } + if (value & (VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT)) { + if (!IsExtEnabled(device_extensions.vk_ext_external_memory_metal)) { + return {vvl::Extension::_VK_EXT_external_memory_metal}; + } + } return {}; case vvl::FlagBitmask::VkExternalSemaphoreHandleTypeFlagBits: if (value & (VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA)) { diff --git a/layers/vulkan/generated/vk_dispatch_table_helper.cpp b/layers/vulkan/generated/vk_dispatch_table_helper.cpp index 5b00b468a76..834bdb49f62 100644 --- a/layers/vulkan/generated/vk_dispatch_table_helper.cpp +++ b/layers/vulkan/generated/vk_dispatch_table_helper.cpp @@ -1237,6 +1237,15 @@ static VKAPI_ATTR VkResult VKAPI_CALL StubGetScreenBufferPropertiesQNX(VkDevice, return VK_SUCCESS; } #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +static VKAPI_ATTR VkResult VKAPI_CALL StubGetMemoryMetalHandleEXT(VkDevice, const VkMemoryGetMetalHandleInfoEXT*, MTLResource_id*) { + return VK_SUCCESS; +} +static VKAPI_ATTR VkResult VKAPI_CALL StubGetMemoryMetalHandlePropertiesEXT(VkDevice, VkExternalMemoryHandleTypeFlagBits, + MTLResource_id, VkMemoryMetalHandlePropertiesEXT*) { + return VK_SUCCESS; +} +#endif // VK_USE_PLATFORM_METAL_EXT static VKAPI_ATTR VkResult VKAPI_CALL StubCreateAccelerationStructureKHR(VkDevice, const VkAccelerationStructureCreateInfoKHR*, const VkAllocationCallbacks*, VkAccelerationStructureKHR*) { @@ -1776,6 +1785,8 @@ const auto& GetApiExtensionMap() { {"vkQueueNotifyOutOfBandNV", {vvl::Extension::_VK_NV_low_latency2}}, {"vkCmdSetAttachmentFeedbackLoopEnableEXT", {vvl::Extension::_VK_EXT_attachment_feedback_loop_dynamic_state}}, {"vkGetScreenBufferPropertiesQNX", {vvl::Extension::_VK_QNX_external_memory_screen_buffer}}, + {"vkGetMemoryMetalHandleEXT", {vvl::Extension::_VK_EXT_external_memory_metal}}, + {"vkGetMemoryMetalHandlePropertiesEXT", {vvl::Extension::_VK_EXT_external_memory_metal}}, {"vkCreateAccelerationStructureKHR", {vvl::Extension::_VK_KHR_acceleration_structure}}, {"vkDestroyAccelerationStructureKHR", {vvl::Extension::_VK_KHR_acceleration_structure}}, {"vkCmdBuildAccelerationStructuresKHR", {vvl::Extension::_VK_KHR_acceleration_structure}}, @@ -3875,6 +3886,17 @@ void layer_init_device_dispatch_table(VkDevice device, VkLayerDispatchTable* tab table->GetScreenBufferPropertiesQNX = (PFN_vkGetScreenBufferPropertiesQNX)StubGetScreenBufferPropertiesQNX; } #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + table->GetMemoryMetalHandleEXT = (PFN_vkGetMemoryMetalHandleEXT)gpa(device, "vkGetMemoryMetalHandleEXT"); + if (table->GetMemoryMetalHandleEXT == nullptr) { + table->GetMemoryMetalHandleEXT = (PFN_vkGetMemoryMetalHandleEXT)StubGetMemoryMetalHandleEXT; + } + table->GetMemoryMetalHandlePropertiesEXT = + (PFN_vkGetMemoryMetalHandlePropertiesEXT)gpa(device, "vkGetMemoryMetalHandlePropertiesEXT"); + if (table->GetMemoryMetalHandlePropertiesEXT == nullptr) { + table->GetMemoryMetalHandlePropertiesEXT = (PFN_vkGetMemoryMetalHandlePropertiesEXT)StubGetMemoryMetalHandlePropertiesEXT; + } +#endif // VK_USE_PLATFORM_METAL_EXT table->CreateAccelerationStructureKHR = (PFN_vkCreateAccelerationStructureKHR)gpa(device, "vkCreateAccelerationStructureKHR"); if (table->CreateAccelerationStructureKHR == nullptr) { table->CreateAccelerationStructureKHR = (PFN_vkCreateAccelerationStructureKHR)StubCreateAccelerationStructureKHR; diff --git a/layers/vulkan/generated/vk_extension_helper.cpp b/layers/vulkan/generated/vk_extension_helper.cpp index df26cbc8649..93e5934d75c 100644 --- a/layers/vulkan/generated/vk_extension_helper.cpp +++ b/layers/vulkan/generated/vk_extension_helper.cpp @@ -400,6 +400,7 @@ vvl::Extension GetExtension(std::string extension) { {"VK_EXT_shader_replicated_composites", vvl::Extension::_VK_EXT_shader_replicated_composites}, {"VK_NV_ray_tracing_validation", vvl::Extension::_VK_NV_ray_tracing_validation}, {"VK_MESA_image_alignment_control", vvl::Extension::_VK_MESA_image_alignment_control}, + {"VK_EXT_external_memory_metal", vvl::Extension::_VK_EXT_external_memory_metal}, {"VK_KHR_acceleration_structure", vvl::Extension::_VK_KHR_acceleration_structure}, {"VK_KHR_ray_tracing_pipeline", vvl::Extension::_VK_KHR_ray_tracing_pipeline}, {"VK_KHR_ray_query", vvl::Extension::_VK_KHR_ray_query}, diff --git a/layers/vulkan/generated/vk_extension_helper.h b/layers/vulkan/generated/vk_extension_helper.h index 15d241d7e59..e1cb8fc8302 100644 --- a/layers/vulkan/generated/vk_extension_helper.h +++ b/layers/vulkan/generated/vk_extension_helper.h @@ -614,6 +614,7 @@ struct DeviceExtensions : public InstanceExtensions { ExtEnabled vk_ext_shader_replicated_composites{kNotEnabled}; ExtEnabled vk_nv_ray_tracing_validation{kNotEnabled}; ExtEnabled vk_mesa_image_alignment_control{kNotEnabled}; + ExtEnabled vk_ext_external_memory_metal{kNotEnabled}; ExtEnabled vk_khr_acceleration_structure{kNotEnabled}; ExtEnabled vk_khr_ray_tracing_pipeline{kNotEnabled}; ExtEnabled vk_khr_ray_query{kNotEnabled}; @@ -1661,6 +1662,11 @@ struct DeviceExtensions : public InstanceExtensions { {vvl::Extension::_VK_MESA_image_alignment_control, Info(&DeviceExtensions::vk_mesa_image_alignment_control, {{{&DeviceExtensions::vk_khr_get_physical_device_properties2, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}}})}, +#ifdef VK_USE_PLATFORM_METAL_EXT + {vvl::Extension::_VK_EXT_external_memory_metal, + Info(&DeviceExtensions::vk_ext_external_memory_metal, + {{{&DeviceExtensions::vk_khr_external_memory, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME}}})}, +#endif // VK_USE_PLATFORM_METAL_EXT {vvl::Extension::_VK_KHR_acceleration_structure, Info(&DeviceExtensions::vk_khr_acceleration_structure, {{{&DeviceExtensions::vk_feature_version_1_1, "VK_VERSION_1_1"}, @@ -2083,6 +2089,7 @@ constexpr bool IsDeviceExtension(vvl::Extension extension) { case vvl::Extension::_VK_EXT_shader_replicated_composites: case vvl::Extension::_VK_NV_ray_tracing_validation: case vvl::Extension::_VK_MESA_image_alignment_control: + case vvl::Extension::_VK_EXT_external_memory_metal: case vvl::Extension::_VK_KHR_acceleration_structure: case vvl::Extension::_VK_KHR_ray_tracing_pipeline: case vvl::Extension::_VK_KHR_ray_query: diff --git a/layers/vulkan/generated/vk_function_pointers.cpp b/layers/vulkan/generated/vk_function_pointers.cpp index 29110d4c562..edd47b42975 100644 --- a/layers/vulkan/generated/vk_function_pointers.cpp +++ b/layers/vulkan/generated/vk_function_pointers.cpp @@ -782,6 +782,10 @@ PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT CmdSetAttachmentFeedbackLoopEnableEX #ifdef VK_USE_PLATFORM_SCREEN_QNX PFN_vkGetScreenBufferPropertiesQNX GetScreenBufferPropertiesQNX; #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +PFN_vkGetMemoryMetalHandleEXT GetMemoryMetalHandleEXT; +PFN_vkGetMemoryMetalHandlePropertiesEXT GetMemoryMetalHandlePropertiesEXT; +#endif // VK_USE_PLATFORM_METAL_EXT PFN_vkCreateAccelerationStructureKHR CreateAccelerationStructureKHR; PFN_vkDestroyAccelerationStructureKHR DestroyAccelerationStructureKHR; PFN_vkCmdBuildAccelerationStructuresKHR CmdBuildAccelerationStructuresKHR; @@ -2389,6 +2393,14 @@ void InitDeviceExtension(VkInstance instance, VkDevice device, const char* exten } }, #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + { + "VK_EXT_external_memory_metal", [](VkInstance , VkDevice device) { + GetMemoryMetalHandleEXT = reinterpret_cast(GetDeviceProcAddr(device, "vkGetMemoryMetalHandleEXT")); + GetMemoryMetalHandlePropertiesEXT = reinterpret_cast(GetDeviceProcAddr(device, "vkGetMemoryMetalHandlePropertiesEXT")); + } + }, +#endif // VK_USE_PLATFORM_METAL_EXT { "VK_KHR_acceleration_structure", [](VkInstance , VkDevice device) { CreateAccelerationStructureKHR = reinterpret_cast(GetDeviceProcAddr(device, "vkCreateAccelerationStructureKHR")); @@ -2925,6 +2937,10 @@ void ResetAllExtensions() { #ifdef VK_USE_PLATFORM_SCREEN_QNX GetScreenBufferPropertiesQNX = nullptr; #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + GetMemoryMetalHandleEXT = nullptr; + GetMemoryMetalHandlePropertiesEXT = nullptr; +#endif // VK_USE_PLATFORM_METAL_EXT CreateAccelerationStructureKHR = nullptr; DestroyAccelerationStructureKHR = nullptr; CmdBuildAccelerationStructuresKHR = nullptr; diff --git a/layers/vulkan/generated/vk_function_pointers.h b/layers/vulkan/generated/vk_function_pointers.h index aaa6228cd82..0eb3b373307 100644 --- a/layers/vulkan/generated/vk_function_pointers.h +++ b/layers/vulkan/generated/vk_function_pointers.h @@ -745,6 +745,10 @@ extern PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT CmdSetAttachmentFeedbackLoopE #ifdef VK_USE_PLATFORM_SCREEN_QNX extern PFN_vkGetScreenBufferPropertiesQNX GetScreenBufferPropertiesQNX; #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT +extern PFN_vkGetMemoryMetalHandleEXT GetMemoryMetalHandleEXT; +extern PFN_vkGetMemoryMetalHandlePropertiesEXT GetMemoryMetalHandlePropertiesEXT; +#endif // VK_USE_PLATFORM_METAL_EXT extern PFN_vkCreateAccelerationStructureKHR CreateAccelerationStructureKHR; extern PFN_vkDestroyAccelerationStructureKHR DestroyAccelerationStructureKHR; extern PFN_vkCmdBuildAccelerationStructuresKHR CmdBuildAccelerationStructuresKHR; diff --git a/layers/vulkan/generated/vk_layer_dispatch_table.h b/layers/vulkan/generated/vk_layer_dispatch_table.h index 9d9344d215c..b73222b467c 100644 --- a/layers/vulkan/generated/vk_layer_dispatch_table.h +++ b/layers/vulkan/generated/vk_layer_dispatch_table.h @@ -743,6 +743,10 @@ typedef struct VkLayerDispatchTable_ { #ifdef VK_USE_PLATFORM_SCREEN_QNX PFN_vkGetScreenBufferPropertiesQNX GetScreenBufferPropertiesQNX; #endif // VK_USE_PLATFORM_SCREEN_QNX +#ifdef VK_USE_PLATFORM_METAL_EXT + PFN_vkGetMemoryMetalHandleEXT GetMemoryMetalHandleEXT; + PFN_vkGetMemoryMetalHandlePropertiesEXT GetMemoryMetalHandlePropertiesEXT; +#endif // VK_USE_PLATFORM_METAL_EXT PFN_vkCreateAccelerationStructureKHR CreateAccelerationStructureKHR; PFN_vkDestroyAccelerationStructureKHR DestroyAccelerationStructureKHR; PFN_vkCmdBuildAccelerationStructuresKHR CmdBuildAccelerationStructuresKHR; diff --git a/scripts/known_good.json b/scripts/known_good.json index d12029afded..62fddfc54f1 100755 --- a/scripts/known_good.json +++ b/scripts/known_good.json @@ -3,19 +3,19 @@ { "name": "Vulkan-Headers", "api": "vulkan", - "url": "https://github.com/KhronosGroup/Vulkan-Headers.git", + "url": "https://github.com/aitor-lunarg/Vulkan-Headers.git", "sub_dir": "Vulkan-Headers", "build_dir": "Vulkan-Headers/build", "install_dir": "Vulkan-Headers/build/install", - "commit": "v1.3.293" + "commit": "ee1856db19e1aaff01de3d54e7d83d3cbb539e3e" }, { "name": "Vulkan-Utility-Libraries", - "url": "https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git", + "url": "https://github.com/aitor-lunarg/Vulkan-Utility-Libraries.git", "sub_dir": "Vulkan-Utility-Libraries", "build_dir": "Vulkan-Utility-Libraries/build", "install_dir": "Vulkan-Utility-Libraries/build/install", - "commit": "v1.3.293", + "commit": "321f4d102bf0d0b2d79fdccd738365fc1a34e068", "deps": [ { "var_name": "VULKAN_HEADERS_INSTALL_DIR", From 62812ecc1d6000b2e6116c246083b1b8935b6d3b Mon Sep 17 00:00:00 2001 From: Aitor Camacho Date: Thu, 5 Sep 2024 20:21:05 +0900 Subject: [PATCH 2/4] tests: Add VK_EXT_external_memory_metal tests --- tests/CMakeLists.txt | 1 + tests/unit/external_memory_metal.cpp | 382 +++++++++++++++++++++++++++ 2 files changed, 383 insertions(+) create mode 100644 tests/unit/external_memory_metal.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e48a766fd62..4142bdcc5a7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -91,6 +91,7 @@ target_sources(vk_layer_validation_tests PRIVATE unit/dynamic_rendering_local_read_positive.cpp unit/dynamic_state.cpp unit/dynamic_state_positive.cpp + unit/external_memory_metal.cpp unit/external_memory_sync.cpp unit/external_memory_sync_positive.cpp unit/fragment_shading_rate.cpp diff --git a/tests/unit/external_memory_metal.cpp b/tests/unit/external_memory_metal.cpp new file mode 100644 index 00000000000..0bd9919f06a --- /dev/null +++ b/tests/unit/external_memory_metal.cpp @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2015-2024 The Khronos Group Inc. + * Copyright (c) 2015-2024 Valve Corporation + * Copyright (c) 2015-2024 LunarG, Inc. + * Copyright (c) 2015-2024 Google, Inc. + * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +#include "utils/vk_layer_utils.h" +#include "../framework/layer_validation_tests.h" +#include "../framework/external_memory_sync.h" + +#ifdef VK_USE_PLATFORM_METAL_EXT + +class NegativeExternalMemoryMetal : public VkLayerTest {}; + +TEST_F(NegativeExternalMemoryMetal, AllocateExportableImageWithoutDedicatedAllocationInPNext) { + TEST_DESCRIPTION("Allocate exportable metal texture without dedicated allocation in pNext chain"); + + AddRequiredExtensions(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); + AddRequiredExtensions(VK_EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME); + RETURN_IF_SKIP(Init()); + + // Create export image + VkExternalMemoryImageCreateInfo external_image_info = vku::InitStructHelper(); + VkImageCreateInfo image_info = vku::InitStructHelper(&external_image_info); + image_info.imageType = VK_IMAGE_TYPE_2D; + image_info.arrayLayers = 1; + image_info.extent = {64, 64, 1}; + image_info.format = VK_FORMAT_R8G8B8A8_UNORM; + image_info.mipLevels = 1; + image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + image_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + + auto exportable_types = FindSupportedExternalMemoryHandleTypes(gpu(), image_info, VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT); + + VkExternalMemoryHandleTypeFlagBits metal_texture_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT; + if ((exportable_types & metal_texture_type) == 0u) { + GTEST_SKIP() << "Unable to find exportable metal texture handle type"; + } + external_image_info.handleTypes = metal_texture_type; + vkt::Image image(*m_device, image_info, vkt::no_mem); + + VkExportMemoryAllocateInfo export_memory_info = vku::InitStructHelper(nullptr); + export_memory_info.handleTypes = metal_texture_type; + + auto alloc_info = vkt::DeviceMemory::get_resource_alloc_info(*m_device, image.memory_requirements(), + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &export_memory_info); + m_errorMonitor->SetDesiredError("VUID-UNASSIGNED-VK_EXT_external_memory-no-VkMemoryDedicatedAllocateInfo-export"); + image.memory().try_init(*m_device, alloc_info); + m_errorMonitor->VerifyFound(); +} + +TEST_F(NegativeExternalMemoryMetal, InvalidImportType) { + TEST_DESCRIPTION("Import metal resource with invalid handle type"); + + AddRequiredExtensions(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); + AddRequiredExtensions(VK_EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME); + RETURN_IF_SKIP(Init()); + + VkExternalMemoryBufferCreateInfo external_buffer_info = vku::InitStructHelper(); + const auto buffer_info = vkt::Buffer::create_info(4096, VK_BUFFER_USAGE_TRANSFER_DST_BIT, nullptr, &external_buffer_info); + const auto exportable_types = + FindSupportedExternalMemoryHandleTypes(gpu(), buffer_info, VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT); + + auto metal_types = static_cast(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT | + VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT); + auto valid_types = static_cast(exportable_types & metal_types); + if (valid_types == 0u) { + GTEST_SKIP() << "Unable to find exportable metal handle type"; + } + const auto handle_type = LeastSignificantFlag(valid_types); + external_buffer_info.handleTypes = handle_type; + vkt::Buffer buffer(*m_device, buffer_info, vkt::no_mem); + + // Check if dedicated allocation is required + bool dedicated_allocation = false; + IterateFlags(exportable_types, [&](VkExternalMemoryHandleTypeFlagBits handle_type) { + if (HandleTypeNeedsDedicatedAllocation(gpu(), buffer_info, handle_type)) { + dedicated_allocation = true; + } + }); + VkMemoryDedicatedAllocateInfo dedicated_info = vku::InitStructHelper(); + dedicated_info.buffer = buffer; + + VkExportMemoryAllocateInfo export_memory_info = vku::InitStructHelper(dedicated_allocation ? &dedicated_info : nullptr); + export_memory_info.handleTypes = handle_type; + + auto alloc_info = vkt::DeviceMemory::get_resource_alloc_info(*m_device, buffer.memory_requirements(), + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &export_memory_info); + VkResult result = buffer.memory().try_init(*m_device, alloc_info); + if (result != VK_SUCCESS) { + GTEST_SKIP() << "vkAllocateMemory failed. Unable to continue test to check for incorrect import handle type."; + } + + VkMemoryGetMetalHandleInfoEXT get_handle_info = vku::InitStructHelper(); + get_handle_info.handleType = handle_type; + get_handle_info.memory = buffer.memory().handle(); + MTLResource_id import_handle = nullptr; + vk::GetMemoryMetalHandleEXT(*m_device, &get_handle_info, &import_handle); + + VkImportMemoryMetalHandleInfoEXT metal_import_info = vku::InitStructHelper(); + metal_import_info.handleType = metal_types; + metal_import_info.handle = import_handle; + VkMemoryAllocateInfo import_allocate_info = vku::InitStructHelper(&metal_import_info); + VkDeviceMemory device_memory = VK_NULL_HANDLE; + m_errorMonitor->SetDesiredError("VUID-VK_EXT_external_memory-incorrect-handle-type"); + // Since we are using two bits to import the memory which is not allowed, we will trigger this undefined VUID + m_errorMonitor->SetAllowedFailureMsg("VUID_Undefined"); + vk::AllocateMemory(*m_device, &import_allocate_info, nullptr, &device_memory); + m_errorMonitor->VerifyFound(); +} + +TEST_F(NegativeExternalMemoryMetal, AllocateImportableImageWithoutDedicatedAllocationInPNext) { + TEST_DESCRIPTION("Import metal texture at allocation without dedicated allocation in pNext chain"); + + AddRequiredExtensions(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); + AddRequiredExtensions(VK_EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME); + RETURN_IF_SKIP(Init()); + + // Create export image + VkExternalMemoryImageCreateInfo external_image_info = vku::InitStructHelper(); + VkImageCreateInfo image_info = vku::InitStructHelper(&external_image_info); + image_info.imageType = VK_IMAGE_TYPE_2D; + image_info.arrayLayers = 1; + image_info.extent = {64, 64, 1}; + image_info.format = VK_FORMAT_R8G8B8A8_UNORM; + image_info.mipLevels = 1; + image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + image_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + + auto exportable_types = FindSupportedExternalMemoryHandleTypes( + gpu(), image_info, VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT); + + VkExternalMemoryHandleTypeFlagBits metal_texture_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT; + if ((exportable_types & metal_texture_type) == 0u) { + GTEST_SKIP() << "Unable to find exportable metal texture handle type"; + } + external_image_info.handleTypes = metal_texture_type; + vkt::Image image(*m_device, image_info, vkt::no_mem); + + VkMemoryDedicatedAllocateInfo dedicated_info = vku::InitStructHelper(); + dedicated_info.image = image.handle(); + VkExportMemoryAllocateInfo export_memory_info = vku::InitStructHelper(&dedicated_info); + export_memory_info.handleTypes = metal_texture_type; + image.allocate_and_bind_memory(*m_device, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &export_memory_info); + + VkMemoryGetMetalHandleInfoEXT get_handle_info = vku::InitStructHelper(); + get_handle_info.handleType = metal_texture_type; + get_handle_info.memory = image.memory().handle(); + MTLResource_id import_handle = nullptr; + vk::GetMemoryMetalHandleEXT(*m_device, &get_handle_info, &import_handle); + + VkImportMemoryMetalHandleInfoEXT metal_import_info = vku::InitStructHelper(); + metal_import_info.handleType = metal_texture_type; + metal_import_info.handle = import_handle; + VkMemoryAllocateInfo import_allocate_info = vku::InitStructHelper(&metal_import_info); + VkDeviceMemory device_memory = VK_NULL_HANDLE; + m_errorMonitor->SetDesiredError("VUID-UNASSIGNED-VK_EXT_external_memory-no-VkMemoryDedicatedAllocateInfo-import"); + vk::AllocateMemory(*m_device, &import_allocate_info, nullptr, &device_memory); + m_errorMonitor->VerifyFound(); +} + +TEST_F(NegativeExternalMemoryMetal, AllocateImportableImageWithoutDedicatedImageAllocation) { + TEST_DESCRIPTION("Import invalid metal texture without dedicated image specified"); + + AddRequiredExtensions(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); + AddRequiredExtensions(VK_EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME); + RETURN_IF_SKIP(Init()); + + // Create export image + VkExternalMemoryImageCreateInfo external_image_info = vku::InitStructHelper(); + VkImageCreateInfo image_info = vku::InitStructHelper(&external_image_info); + image_info.imageType = VK_IMAGE_TYPE_2D; + image_info.arrayLayers = 1; + image_info.extent = {64, 64, 1}; + image_info.format = VK_FORMAT_R8G8B8A8_UNORM; + image_info.mipLevels = 1; + image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + image_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + + auto exportable_types = FindSupportedExternalMemoryHandleTypes( + gpu(), image_info, VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT); + + VkExternalMemoryHandleTypeFlagBits metal_texture_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT; + if ((exportable_types & metal_texture_type) == 0u) { + GTEST_SKIP() << "Unable to find exportable metal texture handle type"; + } + external_image_info.handleTypes = metal_texture_type; + vkt::Image image(*m_device, image_info, vkt::no_mem); + + VkMemoryDedicatedAllocateInfo dedicated_info = vku::InitStructHelper(); + dedicated_info.image = image.handle(); + VkExportMemoryAllocateInfo export_memory_info = vku::InitStructHelper(&dedicated_info); + export_memory_info.handleTypes = metal_texture_type; + image.allocate_and_bind_memory(*m_device, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &export_memory_info); + + VkMemoryGetMetalHandleInfoEXT get_handle_info = vku::InitStructHelper(); + get_handle_info.handleType = metal_texture_type; + get_handle_info.memory = image.memory().handle(); + MTLResource_id import_handle = nullptr; + vk::GetMemoryMetalHandleEXT(*m_device, &get_handle_info, &import_handle); + + dedicated_info.image = VK_NULL_HANDLE; // This is what makes it ilegal + VkImportMemoryMetalHandleInfoEXT metal_import_info = vku::InitStructHelper(&dedicated_info); + metal_import_info.handleType = metal_texture_type; + metal_import_info.handle = import_handle; + VkMemoryAllocateInfo import_allocate_info = vku::InitStructHelper(&metal_import_info); + VkDeviceMemory device_memory = VK_NULL_HANDLE; + m_errorMonitor->SetDesiredError("VUID-UNASSIGNED-VK_EXT_external_memory-dedicated-null-image-import"); + vk::AllocateMemory(*m_device, &import_allocate_info, nullptr, &device_memory); + m_errorMonitor->VerifyFound(); +} + +TEST_F(NegativeExternalMemoryMetal, GetResourceHandleWithoutExportStructAtCreation) { + TEST_DESCRIPTION("Get resource handle that was created without the export struct at creation"); + + AddRequiredExtensions(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); + AddRequiredExtensions(VK_EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME); + RETURN_IF_SKIP(Init()); + + VkExternalMemoryBufferCreateInfo external_buffer_info = vku::InitStructHelper(); + const auto buffer_info = vkt::Buffer::create_info(4096, VK_BUFFER_USAGE_TRANSFER_DST_BIT, nullptr, &external_buffer_info); + const auto exportable_types = + FindSupportedExternalMemoryHandleTypes(gpu(), buffer_info, VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT); + + auto metal_types = static_cast(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT | + VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT); + auto valid_types = static_cast(exportable_types & metal_types); + if (valid_types == 0u) { + GTEST_SKIP() << "Unable to find exportable metal handle type"; + } + const auto handle_type = LeastSignificantFlag(valid_types); + external_buffer_info.handleTypes = handle_type; + vkt::Buffer buffer(*m_device, buffer_info, vkt::no_mem); + + // Check if dedicated allocation is required + bool dedicated_allocation = false; + IterateFlags(exportable_types, [&](VkExternalMemoryHandleTypeFlagBits handle_type) { + if (HandleTypeNeedsDedicatedAllocation(gpu(), buffer_info, handle_type)) { + dedicated_allocation = true; + } + }); + VkMemoryDedicatedAllocateInfo dedicated_info = vku::InitStructHelper(); + dedicated_info.buffer = buffer; + + auto alloc_info = vkt::DeviceMemory::get_resource_alloc_info(*m_device, buffer.memory_requirements(), + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, dedicated_allocation ? &dedicated_info : nullptr); + VkResult result = buffer.memory().try_init(*m_device, alloc_info); + if (result != VK_SUCCESS) { + GTEST_SKIP() << "vkAllocateMemory failed. Unable to continue test to check for incorrect import handle type."; + } + + MTLResource_id handle = nullptr; + VkMemoryGetMetalHandleInfoEXT get_handle_info = vku::InitStructHelper(); + get_handle_info.memory = buffer.memory().handle(); + get_handle_info.handleType = handle_type; + m_errorMonitor->SetDesiredError("VUID-UNASSIGNED-VK_EXT_external_memory-memory-not-created-with-VkExportMemoryAllocateInfo"); + vk::GetMemoryMetalHandleEXT(*m_device, &get_handle_info, &handle); + m_errorMonitor->VerifyFound(); +} + +TEST_F(NegativeExternalMemoryMetal, GetResourceHandleWithIncorrectHandleType) { + TEST_DESCRIPTION("Get resource handle that was created with a different external handle type"); + + AddRequiredExtensions(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); + AddRequiredExtensions(VK_EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME); + RETURN_IF_SKIP(Init()); + + VkExternalMemoryBufferCreateInfo external_buffer_info = vku::InitStructHelper(); + const auto buffer_info = vkt::Buffer::create_info(4096, VK_BUFFER_USAGE_TRANSFER_DST_BIT, nullptr, &external_buffer_info); + const auto exportable_types = + FindSupportedExternalMemoryHandleTypes(gpu(), buffer_info, VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT); + + auto metal_types = static_cast(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT | + VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT); + auto valid_types = static_cast(exportable_types & metal_types); + if (valid_types == 0u) { + GTEST_SKIP() << "Unable to find exportable metal handle type"; + } + const auto handle_type = LeastSignificantFlag(valid_types); + external_buffer_info.handleTypes = handle_type; + vkt::Buffer buffer(*m_device, buffer_info, vkt::no_mem); + + // Check if dedicated allocation is required + bool dedicated_allocation = false; + IterateFlags(exportable_types, [&](VkExternalMemoryHandleTypeFlagBits handle_type) { + if (HandleTypeNeedsDedicatedAllocation(gpu(), buffer_info, handle_type)) { + dedicated_allocation = true; + } + }); + VkMemoryDedicatedAllocateInfo dedicated_info = vku::InitStructHelper(); + dedicated_info.buffer = buffer; + + VkExportMemoryAllocateInfo export_memory_info = vku::InitStructHelper(dedicated_allocation ? &dedicated_info : nullptr); + export_memory_info.handleTypes = handle_type; + + auto alloc_info = vkt::DeviceMemory::get_resource_alloc_info(*m_device, buffer.memory_requirements(), + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &export_memory_info); + VkResult result = buffer.memory().try_init(*m_device, alloc_info); + if (result != VK_SUCCESS) { + GTEST_SKIP() << "vkAllocateMemory failed. Unable to continue test to check for incorrect import handle type."; + } + + MTLResource_id handle = nullptr; + VkMemoryGetMetalHandleInfoEXT get_handle_info = vku::InitStructHelper(); + get_handle_info.memory = buffer.memory().handle(); + // Get the other handle type that was not used to allocate the memory + get_handle_info.handleType = static_cast(handle_type ^ metal_types); + m_errorMonitor->SetDesiredError("VUID-VK_EXT_external_memory-memory-allocation-missing-handle-type"); + vk::GetMemoryMetalHandleEXT(*m_device, &get_handle_info, &handle); + m_errorMonitor->VerifyFound(); +} + + +TEST_F(NegativeExternalMemoryMetal, GetResourceHandleWithNonMetalHandle) { + TEST_DESCRIPTION("Get resource handle as non metal handle"); + + AddRequiredExtensions(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); + AddRequiredExtensions(VK_EXT_EXTERNAL_MEMORY_METAL_EXTENSION_NAME); + RETURN_IF_SKIP(Init()); + + VkExternalMemoryBufferCreateInfo external_buffer_info = vku::InitStructHelper(); + const auto buffer_info = vkt::Buffer::create_info(4096, VK_BUFFER_USAGE_TRANSFER_DST_BIT, nullptr, &external_buffer_info); + const auto exportable_types = + FindSupportedExternalMemoryHandleTypes(gpu(), buffer_info, VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT); + + auto metal_types = static_cast(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT | + VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT); + auto valid_types = static_cast(exportable_types & metal_types); + if (valid_types == 0u) { + GTEST_SKIP() << "Unable to find exportable metal handle type"; + } + const auto handle_type = LeastSignificantFlag(valid_types); + external_buffer_info.handleTypes = handle_type; + vkt::Buffer buffer(*m_device, buffer_info, vkt::no_mem); + + // Check if dedicated allocation is required + bool dedicated_allocation = false; + IterateFlags(exportable_types, [&](VkExternalMemoryHandleTypeFlagBits handle_type) { + if (HandleTypeNeedsDedicatedAllocation(gpu(), buffer_info, handle_type)) { + dedicated_allocation = true; + } + }); + VkMemoryDedicatedAllocateInfo dedicated_info = vku::InitStructHelper(); + dedicated_info.buffer = buffer; + + VkExportMemoryAllocateInfo export_memory_info = vku::InitStructHelper(dedicated_allocation ? &dedicated_info : nullptr); + export_memory_info.handleTypes = handle_type; + + auto alloc_info = vkt::DeviceMemory::get_resource_alloc_info(*m_device, buffer.memory_requirements(), + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &export_memory_info); + VkResult result = buffer.memory().try_init(*m_device, alloc_info); + if (result != VK_SUCCESS) { + GTEST_SKIP() << "vkAllocateMemory failed. Unable to continue test to check for incorrect import handle type."; + } + + MTLResource_id handle = nullptr; + VkMemoryGetMetalHandleInfoEXT get_handle_info = vku::InitStructHelper(); + get_handle_info.memory = buffer.memory().handle(); + // Get the other handle type that was not used to allocate the memory + get_handle_info.handleType = LeastSignificantFlag(~metal_types); + m_errorMonitor->SetDesiredError("VUID-VK_EXT_external_memory-get-handle-incorrect-handle-type"); + // We are trying to get the handle using a type that was not specified at creation, so we also get this one + m_errorMonitor->SetAllowedFailureMsg("UID-VK_EXT_external_memory-memory-allocation-missing-handle-type"); + vk::GetMemoryMetalHandleEXT(*m_device, &get_handle_info, &handle); + m_errorMonitor->VerifyFound(); +} + +#endif // VK_USE_PLATFORM_METAL_EXT From 042cb3d196d3a8c9c85d06398a81462ce9e279f0 Mon Sep 17 00:00:00 2001 From: Aitor Camacho Date: Wed, 25 Sep 2024 18:34:46 +0900 Subject: [PATCH 3/4] layers: remove UNASSIGNED VUIDs for new added VUIDs --- layers/core_checks/cc_external_object.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/layers/core_checks/cc_external_object.cpp b/layers/core_checks/cc_external_object.cpp index d6050a2b685..076c769c69f 100644 --- a/layers/core_checks/cc_external_object.cpp +++ b/layers/core_checks/cc_external_object.cpp @@ -564,9 +564,14 @@ bool CoreChecks::ValidateAllocateMemoryMetal(const VkMemoryAllocateInfo &allocat // is dedicated to that single resource. // Case 1 and partially 3 - if (const auto export_memory_info = vku::FindStructInPNextChain(allocate_info.pNext)) { - if ((export_memory_info->handleTypes == VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT) && dedicated_allocation_info == nullptr) { - skip |= LogError("VUID-UNASSIGNED-VK_EXT_external_memory-no-VkMemoryDedicatedAllocateInfo-export", device, + // Since we know Metal textures required to be imported as a dedicated allocation, we can do the check directly here instead + // of deferring to the binding call. + const auto export_memory_info = vku::FindStructInPNextChain(allocate_info.pNext); + const auto export_memory_info_nv = vku::FindStructInPNextChain(allocate_info.pNext); + if (export_memory_info || export_memory_info_nv) { + VkExternalMemoryHandleTypeFlags handles = export_memory_info ? export_memory_info->handleTypes : export_memory_info_nv->handleTypes; + if ((handles == VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT) && dedicated_allocation_info == nullptr) { + skip |= LogError(" VUID-VkMemoryAllocateInfo-pNext-00639", device, allocate_info_loc.dot(Field::pNext), "VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT requires textures to be imported as a dedicated" "allocation."); @@ -594,7 +599,7 @@ bool CoreChecks::ValidateAllocateMemoryMetal(const VkMemoryAllocateInfo &allocat // operations on buffers. if(import_memory_metal_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT) { if (dedicated_allocation_info == nullptr) { - skip |= LogError("VUID-UNASSIGNED-VK_EXT_external_memory-no-VkMemoryDedicatedAllocateInfo-import", device, + skip |= LogError("VUID-VK_EXT_external_memory-no-VkMemoryDedicatedAllocateInfo-import", device, allocate_info_loc.dot(Field::pNext), "VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT requires textures to be imported as a dedicated" "allocation."); @@ -604,7 +609,7 @@ bool CoreChecks::ValidateAllocateMemoryMetal(const VkMemoryAllocateInfo &allocat // Unsure if there should be a VUID that enforces image to not be NULL when importing a MTLTEXTURE type if (dedicated_allocation_info->image == VK_NULL_HANDLE) { - skip |= LogError("VUID-UNASSIGNED-VK_EXT_external_memory-dedicated-null-image-import", device, + skip |= LogError("VUID-VK_EXT_external_memory-dedicated-null-image-import", device, allocate_info_loc.dot(Struct::VkMemoryDedicatedAllocateInfo, Field::image), "must be a valid image handle."); // Early out since there's no image in VkMemoryDedicatedAllocateInfoKHR. @@ -622,7 +627,7 @@ bool CoreChecks::ValidateAllocateMemoryMetal(const VkMemoryAllocateInfo &allocat DispatchGetPhysicalDeviceFormatProperties2(physical_device, image_format, &format_properties); if ((external_image_format_properties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0u) { - skip |= LogError("VUID-UNASSIGNED-VK_EXT_external_memory-unsupported-format-import", device, + skip |= LogError("VUID-VK_EXT_external_memory-unsupported-format-import", device, allocate_info_loc.dot(Struct::VkImportMemoryMetalHandleInfoEXT, Field::handleType), "does not support importing image with format %s", string_VkFormat(image_format)); } @@ -642,7 +647,7 @@ bool CoreChecks::PreCallValidateGetMemoryMetalHandleEXT(VkDevice device, ASSERT_AND_RETURN_SKIP(memory); auto export_memory_allocate_info = vku::FindStructInPNextChain(memory->safe_allocate_info.pNext); if (export_memory_allocate_info == nullptr) { - skip |= LogError("VUID-UNASSIGNED-VK_EXT_external_memory-memory-not-created-with-VkExportMemoryAllocateInfo", device, + skip |= LogError("VUID-VK_EXT_external_memory-memory-not-created-with-VkExportMemoryAllocateInfo", device, get_metal_handle_info.dot(Field::memory).dot(Field::pNext), "device memory missing VkExportMemoryAllocateInfo at creation"); } From 76c44a4d067767d9dbd68a8c1a7c9c10c56463b0 Mon Sep 17 00:00:00 2001 From: Aitor Camacho Date: Wed, 25 Sep 2024 18:35:19 +0900 Subject: [PATCH 4/4] tests: Replace UNASSIGNED VUIDs for new ones --- tests/unit/external_memory_metal.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/external_memory_metal.cpp b/tests/unit/external_memory_metal.cpp index 0bd9919f06a..bc4cd5a9384 100644 --- a/tests/unit/external_memory_metal.cpp +++ b/tests/unit/external_memory_metal.cpp @@ -54,7 +54,7 @@ TEST_F(NegativeExternalMemoryMetal, AllocateExportableImageWithoutDedicatedAlloc auto alloc_info = vkt::DeviceMemory::get_resource_alloc_info(*m_device, image.memory_requirements(), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &export_memory_info); - m_errorMonitor->SetDesiredError("VUID-UNASSIGNED-VK_EXT_external_memory-no-VkMemoryDedicatedAllocateInfo-export"); + m_errorMonitor->SetDesiredError("VUID-VkMemoryAllocateInfo-pNext-00639"); image.memory().try_init(*m_device, alloc_info); m_errorMonitor->VerifyFound(); } @@ -166,7 +166,7 @@ TEST_F(NegativeExternalMemoryMetal, AllocateImportableImageWithoutDedicatedAlloc metal_import_info.handle = import_handle; VkMemoryAllocateInfo import_allocate_info = vku::InitStructHelper(&metal_import_info); VkDeviceMemory device_memory = VK_NULL_HANDLE; - m_errorMonitor->SetDesiredError("VUID-UNASSIGNED-VK_EXT_external_memory-no-VkMemoryDedicatedAllocateInfo-import"); + m_errorMonitor->SetDesiredError("VUID-VK_EXT_external_memory-no-VkMemoryDedicatedAllocateInfo-import"); vk::AllocateMemory(*m_device, &import_allocate_info, nullptr, &device_memory); m_errorMonitor->VerifyFound(); } @@ -219,7 +219,7 @@ TEST_F(NegativeExternalMemoryMetal, AllocateImportableImageWithoutDedicatedImage metal_import_info.handle = import_handle; VkMemoryAllocateInfo import_allocate_info = vku::InitStructHelper(&metal_import_info); VkDeviceMemory device_memory = VK_NULL_HANDLE; - m_errorMonitor->SetDesiredError("VUID-UNASSIGNED-VK_EXT_external_memory-dedicated-null-image-import"); + m_errorMonitor->SetDesiredError("VUID-VK_EXT_external_memory-dedicated-null-image-import"); vk::AllocateMemory(*m_device, &import_allocate_info, nullptr, &device_memory); m_errorMonitor->VerifyFound(); } @@ -267,7 +267,7 @@ TEST_F(NegativeExternalMemoryMetal, GetResourceHandleWithoutExportStructAtCreati VkMemoryGetMetalHandleInfoEXT get_handle_info = vku::InitStructHelper(); get_handle_info.memory = buffer.memory().handle(); get_handle_info.handleType = handle_type; - m_errorMonitor->SetDesiredError("VUID-UNASSIGNED-VK_EXT_external_memory-memory-not-created-with-VkExportMemoryAllocateInfo"); + m_errorMonitor->SetDesiredError("VUID-VK_EXT_external_memory-memory-not-created-with-VkExportMemoryAllocateInfo"); vk::GetMemoryMetalHandleEXT(*m_device, &get_handle_info, &handle); m_errorMonitor->VerifyFound(); }