Skip to content

Commit

Permalink
Add VK_EXT_external_memory_metal
Browse files Browse the repository at this point in the history
  • Loading branch information
aitor-lunarg committed Aug 22, 2024
1 parent dad3851 commit 75f35e8
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 42 deletions.
2 changes: 1 addition & 1 deletion ExternalRevisions/Vulkan-Headers_repo_revision
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fc6c06ac529e4b4b6e34c17cc650a8f62dee2eb0
20c2e4fc5722e4ba9f95669448a62860c2a7fbd0
4 changes: 2 additions & 2 deletions MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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."));
Expand Down
4 changes: 3 additions & 1 deletion MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
39 changes: 31 additions & 8 deletions MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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

Expand Down
22 changes: 14 additions & 8 deletions MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<MTLTexture> getMTLTexture() { return _mtlTexture; }

#pragma mark Construction

Expand All @@ -140,6 +137,7 @@ class MVKDeviceMemory : public MVKVulkanAPIDeviceObject {

protected:
friend class MVKBuffer;
friend class MVKImage;
friend class MVKImageMemoryBinding;
friend class MVKImagePlane;

Expand All @@ -154,14 +152,22 @@ class MVKDeviceMemory : public MVKVulkanAPIDeviceObject {
bool ensureHostMemory();
void freeHostMemory();
MVKResource* getDedicatedResource();
void initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes);
void initExternalMemory(MVKImage* dedicatedImage);

MVKSmallVector<MVKBuffer*, 4> _buffers;
MVKSmallVector<MVKImageMemoryBinding*, 4> _imageMemoryBindings;
std::mutex _rezLock;
VkDeviceSize _allocationSize = 0;
MVKMappedMemoryRange _mappedRange;
id<MTLBuffer> _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> _mtlBuffer = nil;
id<MTLTexture> _mtlTexture;
};
id<MTLHeap> _mtlHeap = nil;
void* _pMemory = nullptr;
void* _pHostMemory = nullptr;
Expand All @@ -171,6 +177,6 @@ class MVKDeviceMemory : public MVKVulkanAPIDeviceObject {
MTLCPUCacheMode _mtlCPUCacheMode;
bool _isDedicated = false;
bool _isHostMemImported = false;

VkExternalMemoryHandleTypeFlags _externalMemoryHandleType = 0u;
};

70 changes: 52 additions & 18 deletions MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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<MVKImage*>(pDedicatedInfo->image);
dedicatedBuffer = pDedicatedInfo->buffer;
_isDedicated = dedicatedImage || dedicatedBuffer;
break;
Expand All @@ -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: {
Expand All @@ -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<MTLBuffer>)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<MTLTexture>)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) {
Expand All @@ -370,7 +384,7 @@
}
}
#endif
for (auto& memoryBinding : ((MVKImage*)dedicatedImage)->_memoryBindings) {
for (auto& memoryBinding : dedicatedImage->_memoryBindings) {
_imageMemoryBindings.push_back(memoryBinding);
}
return;
Expand All @@ -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."));
Expand All @@ -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;
Expand Down
9 changes: 6 additions & 3 deletions MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
1 change: 1 addition & 0 deletions MoltenVK/MoltenVK/Layers/MVKExtensions.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
28 changes: 28 additions & 0 deletions MoltenVK/MoltenVK/Vulkan/vulkan.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading

0 comments on commit 75f35e8

Please sign in to comment.