From 75f35e88b7e24e331d9300b67c13a51d8cfc5312 Mon Sep 17 00:00:00 2001 From: Aitor Camacho Date: Fri, 23 Aug 2024 04:33:11 +0900 Subject: [PATCH] Add VK_EXT_external_memory_metal --- .../Vulkan-Headers_repo_revision | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm | 4 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 4 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 39 ++++++++--- .../MoltenVK/GPUObjects/MVKDeviceMemory.h | 22 +++--- .../MoltenVK/GPUObjects/MVKDeviceMemory.mm | 70 ++++++++++++++----- MoltenVK/MoltenVK/GPUObjects/MVKImage.mm | 9 ++- MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm | 2 + MoltenVK/MoltenVK/Layers/MVKExtensions.def | 1 + MoltenVK/MoltenVK/Vulkan/vulkan.mm | 28 ++++++++ fetchDependencies | 2 +- 11 files changed, 141 insertions(+), 42 deletions(-) diff --git a/ExternalRevisions/Vulkan-Headers_repo_revision b/ExternalRevisions/Vulkan-Headers_repo_revision index c2bcadb1f..2d71ac956 100644 --- a/ExternalRevisions/Vulkan-Headers_repo_revision +++ b/ExternalRevisions/Vulkan-Headers_repo_revision @@ -1 +1 @@ -fc6c06ac529e4b4b6e34c17cc650a8f62dee2eb0 +20c2e4fc5722e4ba9f95669448a62860c2a7fbd0 diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm index 376109e59..cdaa191b4 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm @@ -236,9 +236,9 @@ void MVKBuffer::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes) { if ( !handleTypes ) { return; } - if (mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR)) { + if (mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT)) { _externalMemoryHandleTypes = handleTypes; - auto& xmProps = getPhysicalDevice()->getExternalBufferProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR); + auto& xmProps = getPhysicalDevice()->getExternalBufferProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT); _requiresDedicatedMemoryAllocation = _requiresDedicatedMemoryAllocation || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT); } else { setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateBuffer(): Only external memory handle type VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR is supported.")); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 54452b824..e74ef60bb 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -366,7 +366,7 @@ class MVKPhysicalDevice : public MVKDispatchableVulkanAPIObject { VkExternalMemoryProperties& getExternalBufferProperties(VkExternalMemoryHandleTypeFlagBits handleType); /** Returns the external memory properties supported for images for the handle type. */ - VkExternalMemoryProperties& getExternalImageProperties(VkExternalMemoryHandleTypeFlagBits handleType); + VkExternalMemoryProperties& getExternalImageProperties(VkFormat format, VkExternalMemoryHandleTypeFlagBits handleType); #pragma mark Metal @@ -817,6 +817,8 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { /** Returns the Metal objects underpinning the Vulkan objects indicated in the pNext chain of pMetalObjectsInfo. */ void getMetalObjects(VkExportMetalObjectsInfoEXT* pMetalObjectsInfo); + MTLResource_id getResourceIdFromHandle(const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, MTLResource_id* pHandle) const; + #pragma mark Construction diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 5b43ea0de..7d3df7565 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -1312,7 +1312,7 @@ for (auto* nextProps = (VkBaseOutStructure*)pImageFormatProperties->pNext; nextProps; nextProps = nextProps->pNext) { if (nextProps->sType == VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES) { auto* pExtImgFmtProps = (VkExternalImageFormatProperties*)nextProps; - pExtImgFmtProps->externalMemoryProperties = getExternalImageProperties(pExtImgFmtInfo->handleType); + pExtImgFmtProps->externalMemoryProperties = getExternalImageProperties(pImageFormatInfo->format, pExtImgFmtInfo->handleType); } } break; @@ -1370,19 +1370,25 @@ case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT: return _hostPointerExternalMemoryProperties; - case VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR: + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT: return _mtlBufferExternalMemoryProperties; default: return _emptyExtMemProps; } } -VkExternalMemoryProperties& MVKPhysicalDevice::getExternalImageProperties(VkExternalMemoryHandleTypeFlagBits handleType) { +VkExternalMemoryProperties& MVKPhysicalDevice::getExternalImageProperties(VkFormat format, VkExternalMemoryHandleTypeFlagBits handleType) { switch (handleType) { case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT: return _hostPointerExternalMemoryProperties; - case VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR: + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT: + // We cannot export images that have no Metal counterparts. This is because we are emulating them via multiple MTLTextures + // and we would require to export multiple MTLTextures. A possible workaround would be to let the user export them as a + // MTLBuffer that covers all textures' memory. However, this would have limited usage since MoltenVK will only know what + // the layout of that MTLBuffer is and how to read it. + if (_pixelFormats.getChromaSubsamplingPlaneCount(format) > 1u) + return _emptyExtMemProps; return _mtlTextureExternalMemoryProperties; default: return _emptyExtMemProps; @@ -3325,15 +3331,15 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope // Buffers _mtlBufferExternalMemoryProperties.externalMemoryFeatures = (VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT); - _mtlBufferExternalMemoryProperties.exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR; - _mtlBufferExternalMemoryProperties.compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR; + _mtlBufferExternalMemoryProperties.exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT; + _mtlBufferExternalMemoryProperties.compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT; // Images _mtlTextureExternalMemoryProperties.externalMemoryFeatures = (VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT); - _mtlTextureExternalMemoryProperties.exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR; - _mtlTextureExternalMemoryProperties.compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR; + _mtlTextureExternalMemoryProperties.exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT; + _mtlTextureExternalMemoryProperties.compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT; } void MVKPhysicalDevice::initExtensions() { @@ -4784,6 +4790,23 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope } } +MTLResource_id MVKDevice::getResourceIdFromHandle(const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, MTLResource_id* pHandle) const +{ + MTLResource_id handle = nil; + MVKDeviceMemory* memory = (MVKDeviceMemory*)pGetMetalHandleInfo->memory; + switch (pGetMetalHandleInfo->handleType) { + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT: + *pHandle = memory->getMTLBuffer(); + break; + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT: + *pHandle = memory->getMTLTexture(); + break; + default: + break; + } + return handle; +} + #pragma mark Construction diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h index 5449608a5..918999895 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h @@ -26,11 +26,6 @@ class MVKImageMemoryBinding; -// TODO: These are inoperable placeholders until VK_KHR_external_memory_metal defines them properly -static const VkExternalMemoryHandleTypeFlagBits VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM; -static const VkExternalMemoryHandleTypeFlagBits VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM; - - #pragma mark MVKDeviceMemory typedef struct MVKMappedMemoryRange { @@ -128,6 +123,8 @@ class MVKDeviceMemory : public MVKVulkanAPIDeviceObject { /** Returns the Metal resource options used by this memory allocation. */ inline MTLResourceOptions getMTLResourceOptions() { return mvkMTLResourceOptions(_mtlStorageMode, _mtlCPUCacheMode); } + /** Returns the Metal texture underlying this memory allocation. */ + inline id getMTLTexture() { return _mtlTexture; } #pragma mark Construction @@ -140,6 +137,7 @@ class MVKDeviceMemory : public MVKVulkanAPIDeviceObject { protected: friend class MVKBuffer; + friend class MVKImage; friend class MVKImageMemoryBinding; friend class MVKImagePlane; @@ -154,14 +152,22 @@ class MVKDeviceMemory : public MVKVulkanAPIDeviceObject { bool ensureHostMemory(); void freeHostMemory(); MVKResource* getDedicatedResource(); - void initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes); + void initExternalMemory(MVKImage* dedicatedImage); MVKSmallVector _buffers; MVKSmallVector _imageMemoryBindings; std::mutex _rezLock; VkDeviceSize _allocationSize = 0; MVKMappedMemoryRange _mappedRange; - id _mtlBuffer = nil; + // Resource object that spans the whole VkDeviceMemory or supposedly does for the user. + // Due to MVKImages allocating the memory they'll use differently based on some criteria, + // we have no access to that memory unless we store a reference to that MTLTexture. + // This allows us to be able to export said texture when the user requests so from a + // VkDeviceMemory object. + union { + id _mtlBuffer = nil; + id _mtlTexture; + }; id _mtlHeap = nil; void* _pMemory = nullptr; void* _pHostMemory = nullptr; @@ -171,6 +177,6 @@ class MVKDeviceMemory : public MVKVulkanAPIDeviceObject { MTLCPUCacheMode _mtlCPUCacheMode; bool _isDedicated = false; bool _isHostMemImported = false; - + VkExternalMemoryHandleTypeFlags _externalMemoryHandleType = 0u; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.mm index 1ec518488..f16f66578 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.mm @@ -291,14 +291,13 @@ _allocationSize = pAllocateInfo->allocationSize; bool willExportMTLBuffer = false; - VkImage dedicatedImage = VK_NULL_HANDLE; + MVKImage* dedicatedImage = nullptr; VkBuffer dedicatedBuffer = VK_NULL_HANDLE; - VkExternalMemoryHandleTypeFlags handleTypes = 0; for (const auto* next = (const VkBaseInStructure*)pAllocateInfo->pNext; next; next = next->pNext) { switch (next->sType) { case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO: { auto* pDedicatedInfo = (VkMemoryDedicatedAllocateInfo*)next; - dedicatedImage = pDedicatedInfo->image; + dedicatedImage = reinterpret_cast(pDedicatedInfo->image); dedicatedBuffer = pDedicatedInfo->buffer; _isDedicated = dedicatedImage || dedicatedBuffer; break; @@ -322,7 +321,7 @@ } case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO: { auto* pExpMemInfo = (VkExportMemoryAllocateInfo*)next; - handleTypes = pExpMemInfo->handleTypes; + _externalMemoryHandleType = pExpMemInfo->handleTypes; break; } case VK_STRUCTURE_TYPE_IMPORT_METAL_BUFFER_INFO_EXT: { @@ -345,18 +344,33 @@ _vkMemAllocFlags = pMemAllocFlagsInfo->flags; break; } + case VK_STRUCTURE_TYPE_IMPORT_MEMORY_METAL_HANDLE_INFO_EXT: { + const auto* pImportInfo = (VkImportMemoryMetalHandleInfoEXT*)next; + _externalMemoryHandleType = pImportInfo->handleType; + if (pImportInfo->handleType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT) { + [_mtlBuffer release]; // guard against dups + _mtlBuffer = [((id)pImportInfo->handle) retain]; // retained + _mtlStorageMode = _mtlBuffer.storageMode; + _mtlCPUCacheMode = _mtlBuffer.cpuCacheMode; + _allocationSize = _mtlBuffer.length; + _pMemory = isMemoryHostAccessible() ? _mtlBuffer.contents : nullptr; + } else if (pImportInfo->handleType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT) { + [_mtlTexture release]; + _mtlTexture = [((id)pImportInfo->handle) retain]; + } + } default: break; } } - initExternalMemory(handleTypes); // After setting _isDedicated + initExternalMemory(dedicatedImage); // After setting _isDedicated // "Dedicated" means this memory can only be used for this image or buffer. if (dedicatedImage) { #if MVK_MACOS if (isMemoryHostCoherent() ) { - if (!((MVKImage*)dedicatedImage)->_isLinear) { + if (!dedicatedImage->_isLinear) { setConfigurationResult(reportError(VK_ERROR_OUT_OF_DEVICE_MEMORY, "vkAllocateMemory(): Host-coherent VkDeviceMemory objects cannot be associated with optimal-tiling images.")); } else { if (!getMetalFeatures().sharedLinearTextures) { @@ -370,7 +384,7 @@ } } #endif - for (auto& memoryBinding : ((MVKImage*)dedicatedImage)->_memoryBindings) { + for (auto& memoryBinding : dedicatedImage->_memoryBindings) { _imageMemoryBindings.push_back(memoryBinding); } return; @@ -396,21 +410,36 @@ } } -void MVKDeviceMemory::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes) { - if ( !handleTypes ) { return; } +void MVKDeviceMemory::initExternalMemory(MVKImage* dedicatedImage) { + if ( !_externalMemoryHandleType ) { return; } - if ( !mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR) ) { - setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkAllocateMemory(): Only external memory handle types VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR or VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR are supported.")); + if ( !mvkIsOnlyAnyFlagEnabled(_externalMemoryHandleType, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT) ) { + setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkAllocateMemory(): Only external memory handle types VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT or VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT are supported.")); } bool requiresDedicated = false; - if (mvkIsAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR)) { - auto& xmProps = getPhysicalDevice()->getExternalBufferProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR); + if (mvkIsAnyFlagEnabled(_externalMemoryHandleType, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT)) { + auto& xmProps = getPhysicalDevice()->getExternalBufferProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_EXT); requiresDedicated = requiresDedicated || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT); + + // Make sure allocation happens at creation time since we may need to export the memory before usage + ensureMTLBuffer(); } - if (mvkIsAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR)) { - auto& xmProps = getPhysicalDevice()->getExternalImageProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR); - requiresDedicated = requiresDedicated || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT); + if (mvkIsAnyFlagEnabled(_externalMemoryHandleType, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT)) { + // Textures require a dedicated allocation according to the spec + if (dedicatedImage == nullptr) { + setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkAllocateMemory(): External memory requires a dedicated VkImage when a export operation will be done.")); + } + auto& xmProps = getPhysicalDevice()->getExternalImageProperties(dedicatedImage->getVkFormat(), VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT); + // Not all texture formats allow to exporting. Vulkan formats that are emulated through the use of multiple MTLTextures + // cannot be exported as a single MTLTexture, and therefore will have exporting forbidden. + if (!(xmProps.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT)) { + setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkAllocateMemory(): VkImage's VkFormat does not allow exports.")); + } else { + // Make sure allocation happens at creation time since we may need to export the memory before usage + _mtlTexture = [dedicatedImage->getMTLTexture() retain]; + } + requiresDedicated = true; } if (requiresDedicated && !_isDedicated) { setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkAllocateMemory(): External memory requires a dedicated VkBuffer or VkImage.")); @@ -425,8 +454,13 @@ auto imgCopies = _imageMemoryBindings; for (auto& img : imgCopies) { img->bindDeviceMemory(nullptr, 0); } - [_mtlBuffer release]; - _mtlBuffer = nil; + if (_externalMemoryHandleType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT) { + [_mtlTexture release]; + _mtlTexture = nil; + } else { + [_mtlBuffer release]; + _mtlBuffer = nil; + } [_mtlHeap release]; _mtlHeap = nil; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index 107b1d8d8..0d5687cc0 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -48,7 +48,10 @@ MVKImageMemoryBinding* memoryBinding = getMemoryBinding(); MVKDeviceMemory* dvcMem = memoryBinding->_deviceMemory; - if (_image->_ioSurface) { + // Use imported texture if we are binding to a VkDeviceMemory that was created with an import operation + if (dvcMem && (dvcMem->_externalMemoryHandleType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT) && dvcMem->_mtlTexture) { + _mtlTexture = dvcMem->_mtlTexture; + } else if (_image->_ioSurface) { _mtlTexture = [_image->getMTLDevice() newTextureWithDescriptor: mtlTexDesc iosurface: _image->_ioSurface @@ -1380,8 +1383,8 @@ static MTLRegion getMTLRegion(const ImgRgn& imgRgn) { void MVKImage::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes) { if ( !handleTypes ) { return; } - if (mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR)) { - auto& xmProps = getPhysicalDevice()->getExternalImageProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR); + if (mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT)) { + auto& xmProps = getPhysicalDevice()->getExternalImageProperties(_vkFormat, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_EXT); for(auto& memoryBinding : _memoryBindings) { memoryBinding->_externalMemoryHandleTypes = handleTypes; memoryBinding->_requiresDedicatedMemoryAllocation = memoryBinding->_requiresDedicatedMemoryAllocation || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index 12bd51624..5806e7d85 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -771,6 +771,8 @@ ADD_DVC_EXT_ENTRY_POINT(vkCopyMemoryToImageEXT, EXT_HOST_IMAGE_COPY); ADD_DVC_EXT_ENTRY_POINT(vkGetImageSubresourceLayout2EXT, EXT_HOST_IMAGE_COPY); ADD_DVC_EXT_ENTRY_POINT(vkTransitionImageLayoutEXT, EXT_HOST_IMAGE_COPY); + ADD_DVC_EXT_ENTRY_POINT(vkGetMemoryMetalHandleEXT, EXT_EXTERNAL_MEMORY_METAL); + ADD_DVC_EXT_ENTRY_POINT(vkGetMemoryMetalHandlePropertiesEXT, EXT_EXTERNAL_MEMORY_METAL); } void MVKInstance::logVersions() { diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def index 5eea40932..007e23ac6 100644 --- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def +++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def @@ -111,6 +111,7 @@ MVK_EXTENSION(EXT_extended_dynamic_state, EXT_EXTENDED_DYNAMIC_STATE MVK_EXTENSION(EXT_extended_dynamic_state2, EXT_EXTENDED_DYNAMIC_STATE_2, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(EXT_extended_dynamic_state3, EXT_EXTENDED_DYNAMIC_STATE_3, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(EXT_external_memory_host, EXT_EXTERNAL_MEMORY_HOST, DEVICE, 10.11, 8.0, 1.0) +MVK_EXTENSION(EXT_external_memory_metal, EXT_EXTERNAL_MEMORY_METAL, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(EXT_fragment_shader_interlock, EXT_FRAGMENT_SHADER_INTERLOCK, DEVICE, 10.13, 11.0, 1.0) MVK_EXTENSION(EXT_hdr_metadata, EXT_HDR_METADATA, DEVICE, 10.15, MVK_NA, MVK_NA) MVK_EXTENSION(EXT_headless_surface, EXT_HEADLESS_SURFACE, INSTANCE, 10.11, 8.0, 1.0) diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 107a13163..120a283f4 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -3034,6 +3034,34 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkDestroyDeferredOperationKHR( MVK_PUBLIC_VULKAN_CORE_ALIAS(vkGetPhysicalDeviceExternalBufferProperties, KHR); +#pragma mark - +#pragma mark VK_EXT_external_memory_metal extension + +MVK_PUBLIC_VULKAN_SYMBOL VkResult vkGetMemoryMetalHandleEXT( + VkDevice device, + const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo, + MTLResource_id* pHandle) { + + MVKTraceVulkanCallStart(); + MVKDevice* mvkDvc = MVKDevice::getMVKDevice(device); + mvkDvc->getResourceIdFromHandle(pGetMetalHandleInfo, pHandle); + MVKTraceVulkanCallEnd(); + return VK_SUCCESS; +} + +MVK_PUBLIC_VULKAN_SYMBOL VkResult vkGetMemoryMetalHandlePropertiesEXT( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + MTLResource_id handle, + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties) { + + MVKTraceVulkanCallStart(); + // TODO + MVKTraceVulkanCallEnd(); + return VK_SUCCESS; +} + + #pragma mark - #pragma mark VK_KHR_external_semaphore_capabilities extension diff --git a/fetchDependencies b/fetchDependencies index a870c300a..e64d839b9 100755 --- a/fetchDependencies +++ b/fetchDependencies @@ -314,7 +314,7 @@ if [ ! "$V_HEADERS_ROOT" = "" ]; then rm -rf ${REPO_NAME} ln -sfn ${V_HEADERS_ROOT} ${REPO_NAME} else - REPO_URL="https://github.com/KhronosGroup/${REPO_NAME}.git" + REPO_URL="https://github.com/aitor-lunarg/${REPO_NAME}.git" REPO_REV=$(cat "${EXT_REV_DIR}/${REPO_NAME}_repo_revision") update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}