Add support for VK_KHR_external_memory extension.
Functions and functionality supported, but don't currently do anything until Metal-friendly enumerations added to VkExternalMemoryHandleTypeFlagBits. Updated What's New document.
This commit is contained in:
parent
2b3cf6f395
commit
d343fed52e
@ -20,7 +20,10 @@ MoltenVK 1.0.42
|
||||
Released TBD
|
||||
|
||||
- Add support for extensions:
|
||||
- `VK_KHR_external_memory_capabilities`
|
||||
- `VK_KHR_external_memory` (non-functional groundwork for future
|
||||
Metal-resource Vulkan extension).
|
||||
- `VK_KHR_external_memory_capabilities` (non-functional groundwork
|
||||
for future Metal-resource Vulkan extension).
|
||||
- Memory consumption improvements when handling Vulkan commands.
|
||||
- Reinstate `VulkanSamples API-Samples` demo apps and add
|
||||
`input_attachment` and `push_descriptors` demos.
|
||||
|
@ -92,6 +92,7 @@ protected:
|
||||
bool shouldFlushHostMemory();
|
||||
VkResult flushToDevice(VkDeviceSize offset, VkDeviceSize size);
|
||||
VkResult pullFromDevice(VkDeviceSize offset, VkDeviceSize size);
|
||||
void initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes);
|
||||
|
||||
VkBufferUsageFlags _usage;
|
||||
bool _isHostCoherentTexelBuffer = false;
|
||||
|
@ -66,8 +66,8 @@ VkResult MVKBuffer::getMemoryRequirements(const void*, VkMemoryRequirements2* pM
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
|
||||
auto* dedicatedReqs = (VkMemoryDedicatedRequirements*)next;
|
||||
dedicatedReqs->prefersDedicatedAllocation = VK_FALSE;
|
||||
dedicatedReqs->requiresDedicatedAllocation = VK_FALSE;
|
||||
dedicatedReqs->requiresDedicatedAllocation = _requiresDedicatedMemoryAllocation;
|
||||
dedicatedReqs->prefersDedicatedAllocation = dedicatedReqs->requiresDedicatedAllocation;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -192,6 +192,28 @@ id<MTLBuffer> MVKBuffer::getMTLBuffer() {
|
||||
MVKBuffer::MVKBuffer(MVKDevice* device, const VkBufferCreateInfo* pCreateInfo) : MVKResource(device), _usage(pCreateInfo->usage) {
|
||||
_byteAlignment = _device->_pMetalFeatures->mtlBufferAlignment;
|
||||
_byteCount = pCreateInfo->size;
|
||||
|
||||
for (const auto* next = (const VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO: {
|
||||
auto* pExtMemInfo = (const VkExternalMemoryBufferCreateInfo*)next;
|
||||
initExternalMemory(pExtMemInfo->handleTypes);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MVKBuffer::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes) {
|
||||
if (mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR)) {
|
||||
_externalMemoryHandleTypes = handleTypes;
|
||||
auto& xmProps = _device->getPhysicalDevice()->getExternalBufferProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR);
|
||||
_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."));
|
||||
}
|
||||
}
|
||||
|
||||
MVKBuffer::~MVKBuffer() {
|
||||
|
@ -283,6 +283,12 @@ public:
|
||||
/** Returns whether this is a unified memory device. */
|
||||
bool getHasUnifiedMemory();
|
||||
|
||||
/** Returns the external memory properties supported for buffers for the handle type. */
|
||||
VkExternalMemoryProperties& getExternalBufferProperties(VkExternalMemoryHandleTypeFlagBits handleType);
|
||||
|
||||
/** Returns the external memory properties supported for images for the handle type. */
|
||||
VkExternalMemoryProperties& getExternalImageProperties(VkExternalMemoryHandleTypeFlagBits handleType);
|
||||
|
||||
|
||||
#pragma mark Metal
|
||||
|
||||
@ -337,6 +343,7 @@ protected:
|
||||
uint64_t getVRAMSize();
|
||||
uint64_t getRecommendedMaxWorkingSetSize();
|
||||
uint64_t getCurrentAllocatedSize();
|
||||
void initExternalMemoryProperties();
|
||||
void initExtensions();
|
||||
MVKVector<MVKQueueFamily*>& getQueueFamilies();
|
||||
void initPipelineCacheUUID();
|
||||
@ -344,9 +351,6 @@ protected:
|
||||
uint64_t getSpirvCrossRevision();
|
||||
bool getImageViewIsSupported(const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo);
|
||||
void populate(VkPhysicalDeviceIDProperties* pDevIdProps);
|
||||
void populate(VkExternalMemoryProperties& xmProps,
|
||||
VkExternalMemoryHandleTypeFlagBits handleType,
|
||||
VkExternalMemoryHandleTypeFlagBits supportedHandleType);
|
||||
void logGPUInfo();
|
||||
|
||||
id<MTLDevice> _mtlDevice;
|
||||
@ -364,6 +368,8 @@ protected:
|
||||
uint32_t _hostCoherentMemoryTypes;
|
||||
uint32_t _privateMemoryTypes;
|
||||
uint32_t _lazilyAllocatedMemoryTypes;
|
||||
VkExternalMemoryProperties _mtlBufferExternalMemoryProperties;
|
||||
VkExternalMemoryProperties _mtlTextureExternalMemoryProperties;
|
||||
};
|
||||
|
||||
|
||||
|
@ -419,10 +419,7 @@ VkResult MVKPhysicalDevice::getImageFormatProperties(const VkPhysicalDeviceImage
|
||||
for (auto* nextProps = (VkBaseOutStructure*)pImageFormatProperties->pNext; nextProps; nextProps = nextProps->pNext) {
|
||||
if (nextProps->sType == VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES) {
|
||||
auto* pExtImgFmtProps = (VkExternalImageFormatProperties*)nextProps;
|
||||
|
||||
// TODO: This is an inoperable placeholder until VK_KHR_external_memory_metal is ratified and implemented
|
||||
const VkExternalMemoryHandleTypeFlagBits VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM;
|
||||
populate(pExtImgFmtProps->externalMemoryProperties, pExtImgFmtInfo->handleType, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR);
|
||||
pExtImgFmtProps->externalMemoryProperties = getExternalImageProperties(pExtImgFmtInfo->handleType);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -482,24 +479,22 @@ bool MVKPhysicalDevice::getImageViewIsSupported(const VkPhysicalDeviceImageForma
|
||||
|
||||
void MVKPhysicalDevice::getExternalBufferProperties(const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
|
||||
VkExternalBufferProperties* pExternalBufferProperties) {
|
||||
|
||||
// TODO: This is an inoperable placeholder until VK_KHR_external_memory_metal is ratified and implemented
|
||||
const VkExternalMemoryHandleTypeFlagBits VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM;
|
||||
populate(pExternalBufferProperties->externalMemoryProperties, pExternalBufferInfo->handleType, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR);
|
||||
pExternalBufferProperties->externalMemoryProperties = getExternalBufferProperties(pExternalBufferInfo->handleType);
|
||||
}
|
||||
|
||||
// If the handleType is the supported handle type, populates xmProps accordingly, otherwise xmProps is cleared.
|
||||
void MVKPhysicalDevice::populate(VkExternalMemoryProperties& xmProps,
|
||||
VkExternalMemoryHandleTypeFlagBits handleType,
|
||||
VkExternalMemoryHandleTypeFlagBits supportedHandleType) {
|
||||
if (handleType == supportedHandleType) {
|
||||
xmProps.externalMemoryFeatures = (VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
|
||||
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
|
||||
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT);
|
||||
xmProps.exportFromImportedHandleTypes = supportedHandleType;
|
||||
xmProps.compatibleHandleTypes = supportedHandleType;
|
||||
} else {
|
||||
mvkClear(&xmProps);
|
||||
static VkExternalMemoryProperties _emptyExtMemProps = {};
|
||||
|
||||
VkExternalMemoryProperties& MVKPhysicalDevice::getExternalBufferProperties(VkExternalMemoryHandleTypeFlagBits handleType) {
|
||||
switch (handleType) {
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR: return _mtlBufferExternalMemoryProperties;
|
||||
default: return _emptyExtMemProps;
|
||||
}
|
||||
}
|
||||
|
||||
VkExternalMemoryProperties& MVKPhysicalDevice::getExternalImageProperties(VkExternalMemoryHandleTypeFlagBits handleType) {
|
||||
switch (handleType) {
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR: return _mtlTextureExternalMemoryProperties;
|
||||
default: return _emptyExtMemProps;
|
||||
}
|
||||
}
|
||||
|
||||
@ -847,8 +842,9 @@ MVKPhysicalDevice::MVKPhysicalDevice(MVKInstance* mvkInstance, id<MTLDevice> mtl
|
||||
initMetalFeatures(); // Call first.
|
||||
initFeatures(); // Call second.
|
||||
initProperties(); // Call third.
|
||||
initMemoryProperties();
|
||||
initExtensions();
|
||||
initMemoryProperties();
|
||||
initExternalMemoryProperties();
|
||||
logGPUInfo();
|
||||
}
|
||||
|
||||
@ -1973,6 +1969,23 @@ uint64_t MVKPhysicalDevice::getCurrentAllocatedSize() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::initExternalMemoryProperties() {
|
||||
|
||||
// Buffers
|
||||
_mtlBufferExternalMemoryProperties.externalMemoryFeatures = (VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
|
||||
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;
|
||||
|
||||
// Images
|
||||
_mtlTextureExternalMemoryProperties.externalMemoryFeatures = (VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
|
||||
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
|
||||
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT);
|
||||
_mtlTextureExternalMemoryProperties.exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR;
|
||||
_mtlTextureExternalMemoryProperties.compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR;
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::initExtensions() {
|
||||
MVKExtensionList* pWritableExtns = (MVKExtensionList*)&_supportedExtensions;
|
||||
pWritableExtns->disableAllButEnabledDeviceExtensions();
|
||||
|
@ -27,6 +27,10 @@
|
||||
class MVKBuffer;
|
||||
class MVKImage;
|
||||
|
||||
// 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
|
||||
|
||||
@ -141,6 +145,7 @@ protected:
|
||||
bool ensureHostMemory();
|
||||
void freeHostMemory();
|
||||
MVKResource* getDedicatedResource();
|
||||
void initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes);
|
||||
|
||||
MVKVectorInline<MVKBuffer*, 4> _buffers;
|
||||
MVKVectorInline<MVKImage*, 4> _images;
|
||||
|
@ -266,10 +266,7 @@ void MVKDeviceMemory::freeHostMemory() {
|
||||
|
||||
MVKResource* MVKDeviceMemory::getDedicatedResource() {
|
||||
MVKAssert(_isDedicated, "This method should only be called on dedicated allocations!");
|
||||
if (_buffers.empty())
|
||||
return _images[0];
|
||||
else
|
||||
return _buffers[0];
|
||||
return _buffers.empty() ? (MVKResource*)_images[0] : (MVKResource*)_buffers[0];
|
||||
}
|
||||
|
||||
MVKDeviceMemory::MVKDeviceMemory(MVKDevice* device,
|
||||
@ -284,22 +281,28 @@ MVKDeviceMemory::MVKDeviceMemory(MVKDevice* device,
|
||||
|
||||
VkImage dedicatedImage = VK_NULL_HANDLE;
|
||||
VkBuffer dedicatedBuffer = VK_NULL_HANDLE;
|
||||
auto* next = (VkStructureType*)pAllocateInfo->pNext;
|
||||
while (next) {
|
||||
switch (*next) {
|
||||
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO: {
|
||||
auto* pDedicatedInfo = (VkMemoryDedicatedAllocateInfo*)next;
|
||||
dedicatedImage = pDedicatedInfo->image;
|
||||
dedicatedBuffer = pDedicatedInfo->buffer;
|
||||
next = (VkStructureType*)pDedicatedInfo->pNext;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
next = (VkStructureType*)((VkMemoryAllocateInfo*)next)->pNext;
|
||||
break;
|
||||
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;
|
||||
dedicatedBuffer = pDedicatedInfo->buffer;
|
||||
_isDedicated = dedicatedImage || dedicatedBuffer;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO: {
|
||||
auto* pExpMemInfo = (VkExportMemoryAllocateInfo*)next;
|
||||
handleTypes = pExpMemInfo->handleTypes;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
initExternalMemory(handleTypes); // After setting _isDedicated
|
||||
|
||||
// "Dedicated" means this memory can only be used for this image or buffer.
|
||||
if (dedicatedImage) {
|
||||
#if MVK_MACOS
|
||||
@ -316,14 +319,16 @@ MVKDeviceMemory::MVKDeviceMemory(MVKDevice* device,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
_isDedicated = true;
|
||||
_images.push_back((MVKImage*)dedicatedImage);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we can, create a MTLHeap. This should happen before creating the buffer
|
||||
// allowing us to map its contents.
|
||||
if (!dedicatedImage && !dedicatedBuffer) {
|
||||
if (dedicatedBuffer) {
|
||||
_buffers.push_back((MVKBuffer*)dedicatedBuffer);
|
||||
}
|
||||
|
||||
// If we can, create a MTLHeap. This should happen before creating the buffer, allowing us to map its contents.
|
||||
if ( !_isDedicated ) {
|
||||
if (!ensureMTLHeap()) {
|
||||
setConfigurationResult(reportError(VK_ERROR_OUT_OF_DEVICE_MEMORY, "Could not allocate VkDeviceMemory of size %llu bytes.", _allocationSize));
|
||||
return;
|
||||
@ -334,10 +339,26 @@ MVKDeviceMemory::MVKDeviceMemory(MVKDevice* device,
|
||||
if (isMemoryHostCoherent() && !ensureMTLBuffer() ) {
|
||||
setConfigurationResult(reportError(VK_ERROR_OUT_OF_DEVICE_MEMORY, "Could not allocate a host-coherent VkDeviceMemory of size %llu bytes. The maximum memory-aligned size of a host-coherent VkDeviceMemory is %llu bytes.", _allocationSize, _device->_pMetalFeatures->maxMTLBufferSize));
|
||||
}
|
||||
}
|
||||
|
||||
if (dedicatedBuffer) {
|
||||
_isDedicated = true;
|
||||
_buffers.push_back((MVKBuffer*)dedicatedBuffer);
|
||||
void MVKDeviceMemory::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes) {
|
||||
if ( !handleTypes ) { 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."));
|
||||
}
|
||||
|
||||
bool requiresDedicated = false;
|
||||
if (mvkIsAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR)) {
|
||||
auto& xmProps = _device->getPhysicalDevice()->getExternalBufferProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR);
|
||||
requiresDedicated = requiresDedicated || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
|
||||
}
|
||||
if (mvkIsAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR)) {
|
||||
auto& xmProps = _device->getPhysicalDevice()->getExternalImageProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR);
|
||||
requiresDedicated = requiresDedicated || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
|
||||
}
|
||||
if (requiresDedicated && !_isDedicated) {
|
||||
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkAllocateMemory(): External memory requires a dedicated VkBuffer or VkImage."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,6 +235,7 @@ protected:
|
||||
bool validateUseTexelBuffer();
|
||||
void initSubresources(const VkImageCreateInfo* pCreateInfo);
|
||||
void initSubresourceLayout(MVKImageSubresource& imgSubRez);
|
||||
void initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes);
|
||||
id<MTLTexture> newMTLTexture();
|
||||
void releaseMTLTexture();
|
||||
void releaseIOSurface();
|
||||
|
@ -182,8 +182,9 @@ VkResult MVKImage::getMemoryRequirements(const void*, VkMemoryRequirements2* pMe
|
||||
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
|
||||
auto* dedicatedReqs = (VkMemoryDedicatedRequirements*)next;
|
||||
bool writable = mvkIsAnyFlagEnabled(_usage, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
dedicatedReqs->prefersDedicatedAllocation = !_usesTexelBuffer && (writable || !_device->_pMetalFeatures->placementHeaps);
|
||||
dedicatedReqs->requiresDedicatedAllocation = VK_FALSE;
|
||||
dedicatedReqs->requiresDedicatedAllocation = _requiresDedicatedMemoryAllocation;
|
||||
dedicatedReqs->prefersDedicatedAllocation = (dedicatedReqs->requiresDedicatedAllocation ||
|
||||
(!_usesTexelBuffer && (writable || !_device->_pMetalFeatures->placementHeaps)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -615,6 +616,18 @@ MVKImage::MVKImage(MVKDevice* device, const VkImageCreateInfo* pCreateInfo) : MV
|
||||
}
|
||||
|
||||
initSubresources(pCreateInfo);
|
||||
|
||||
for (const auto* next = (const VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO: {
|
||||
auto* pExtMemInfo = (const VkExternalMemoryImageCreateInfo*)next;
|
||||
initExternalMemory(pExtMemInfo->handleTypes);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VkSampleCountFlagBits MVKImage::validateSamples(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {
|
||||
@ -784,6 +797,16 @@ void MVKImage::initSubresourceLayout(MVKImageSubresource& imgSubRez) {
|
||||
layout.depthPitch = bytesPerLayerCurrLevel;
|
||||
}
|
||||
|
||||
void MVKImage::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes) {
|
||||
if (mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR)) {
|
||||
_externalMemoryHandleTypes = handleTypes;
|
||||
auto& xmProps = _device->getPhysicalDevice()->getExternalImageProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR);
|
||||
_requiresDedicatedMemoryAllocation = _requiresDedicatedMemoryAllocation || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
|
||||
} else {
|
||||
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage(): Only external memory handle type VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR is supported."));
|
||||
}
|
||||
}
|
||||
|
||||
MVKImage::~MVKImage() {
|
||||
if (_deviceMemory) { _deviceMemory->removeImage(this); }
|
||||
releaseMTLTexture();
|
||||
|
@ -88,4 +88,6 @@ protected:
|
||||
VkDeviceSize _deviceMemoryOffset = 0;
|
||||
VkDeviceSize _byteCount = 0;
|
||||
VkDeviceSize _byteAlignment = 0;
|
||||
VkExternalMemoryHandleTypeFlags _externalMemoryHandleTypes = 0;
|
||||
bool _requiresDedicatedMemoryAllocation = false;
|
||||
};
|
||||
|
@ -46,6 +46,7 @@ MVK_EXTENSION(KHR_dedicated_allocation, KHR_DEDICATED_ALLOCATION, DEVICE)
|
||||
MVK_EXTENSION(KHR_descriptor_update_template, KHR_DESCRIPTOR_UPDATE_TEMPLATE, DEVICE)
|
||||
MVK_EXTENSION(KHR_device_group, KHR_DEVICE_GROUP, DEVICE)
|
||||
MVK_EXTENSION(KHR_device_group_creation, KHR_DEVICE_GROUP_CREATION, INSTANCE)
|
||||
MVK_EXTENSION(KHR_external_memory, KHR_EXTERNAL_MEMORY, DEVICE)
|
||||
MVK_EXTENSION(KHR_external_memory_capabilities, KHR_EXTERNAL_MEMORY_CAPABILITIES, INSTANCE)
|
||||
MVK_EXTENSION(KHR_get_memory_requirements2, KHR_GET_MEMORY_REQUIREMENTS_2, DEVICE)
|
||||
MVK_EXTENSION(KHR_get_physical_device_properties2, KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2, INSTANCE)
|
||||
|
Loading…
x
Reference in New Issue
Block a user